2013-08-13 6 views
7

मैं ओपनसीएल शैली वैक्टर के लिए क्लैंग के भाषा एक्सटेंशन में उपयोग करने के लिए एक परीक्षण कार्यक्रम लिख रहा हूं। मैं कोड को काम करने के लिए प्राप्त कर सकता हूं लेकिन मुझे इसके एक पहलू को पाने में समस्याएं आ रही हैं। मैं यह समझने में प्रतीत नहीं होता कि कैसे एक स्केलर सरणी से एक वेक्टर में लोड करने के लिए क्लैंग प्राप्त करना है।स्मृति से वैक्टर लोड करने के लिए बेहतर तरीका। (clang)

फिलहाल मैं कुछ ऐसा करना है:

byte16 va = (byte16){ argv[1][start], argv[1][start + 1], argv[1][start + 2], 
         argv[1][start + 3], argv[1][start + 4], argv[1][start + 5], 
         argv[1][start + 6], argv[1][start + 7], argv[1][start + 8], 
         argv[1][start + 9], argv[1][start + 10], argv[1][start + 11], 
         argv[1][start + 12], argv[1][start + 13], argv[1][start + 14], 
         argv[1][start + 15]}; 

मैं करूंगा आदर्श कुछ इस तरह की तरह:

byte16 va = *(byte16 *)(&(argv[1][start])); 

कौन सा मैं आसानी से एआरएम या x86 के लिए उचित intrinsics जरिए कर सकते हैं। लेकिन वह कोड प्रोग्राम को क्रैश करने का कारण बनता है हालांकि यह संकलित करता है।

+0

'memcpy (& va, और argv [1] [start], sizeof (va)) 'काम नहीं है? – jxh

उत्तर

5

x86 पर क्रैश हो सकता है कारणों में से एक संरेखण के मुद्दों के कारण है। मैंने समस्या को पुन: पेश करने के लिए अपने सिस्टम पर झुकाव नहीं किया है, लेकिन मैं इसे जीसीसी के उदाहरण पर प्रदर्शित कर सकता हूं।

आप की तरह कुछ करते हैं:

/* Define a vector type of 16 characters. */ 
typedef char __attribute__ ((vector_size (16))) byte16; 

/* Global pointer. */ 
char * foo; 

byte16 test() 
{ 
    return *(byte16 *)&foo[1]; 
} 

अब अगर आप के साथ एक वेक्टर सक्षम 86 पर यह संकलन:

$ gcc -O3 -march=native -mtune=native a.c 

आप होगा परीक्षण के लिए निम्नलिखित विधानसभा मिलती है:

test: 
    movq foo(%rip), %rax 
    vmovdqa 1(%rax), %xmm0 
    ret 

कृपया ध्यान दें, कि चाल गठबंधन है, जो निश्चित रूप से गलत है। अब, आप मुख्य में इस समारोह इनलाइन अगर होता है, और आप की तरह कुछ होगा: आप ठीक हो जाएगा

int main() 
{ 
    foo = __builtin_malloc (22); 
    byte16 x = *(byte16 *)&foo[1]; 
    return x[0]; 
} 

, और आप असंरेखित अनुदेश मिल जाएगा। यह एक बग है, जिसमें कंपाइलर में बहुत अच्छा फिक्स नहीं है, क्योंकि इसे नए डेटा स्ट्रक्चर आदि के साथ इंटरप्रोसेडुरल ऑप्टिमाइज़ेशन की आवश्यकता होगी।

समस्या की उत्पत्ति यह है कि संकलक मानता है कि संकलक वेक्टर प्रकार गठबंधन होते हैं, इसलिए जब आप गठबंधन वेक्टर प्रकारों की एक सरणी को अव्यवस्थित करते हैं तो आप एक गठबंधन चाल का उपयोग कर सकते हैं। जीसीसी में समस्या के लिए एक समाधान के रूप में एक तरह एक असंरेखित वेक्टर प्रकार को परिभाषित कर सकते हैं:

typedef char __attribute__ ((vector_size (16),aligned (1))) unaligned_byte16; 

और भिन्नता असंरेखित स्मृति के लिए इसका इस्तेमाल।

मुझे यकीन नहीं है कि आप अपने सेटअप में बिल्कुल इस समस्या को मार रहे हैं, लेकिन यह ऐसा कुछ है जिसे मैं आपके कंपाइलर से असेंबली आउटपुट का निरीक्षण करके जांचने की सलाह दूंगा।

+0

ठीक है, उस मामले में मुझे कोई कारण नहीं दिख रहा है कि यह क्यों विफल होना चाहिए ... आप ऐसा कुछ करने का प्रयास कर सकते हैं: 'struct b16 { char x [16]; }; संरचना बी 16 एक्स = * (संरचना बी 16 *) और argv [1] [0]; ' –

+1

मैंने क्लैंग का उपयोग करके और असेंबली का निरीक्षण करने (एआरएम असेंबली," '64:" या "': 128 '"पता फ़ील्ड में) मैं देख सकता था कि यह लोड और स्टोर निर्देशों के गठबंधन संस्करणों का उपयोग कर रहा था। यह समाधान मेरे लिए काम करता है। – sh1

संबंधित मुद्दे