2016-07-28 23 views
5

हाय सब लोग मुझे बहुतमुद्दे

void test() 
{ 
    uint16_t n1 = 5; 
    uint16_t n2 = 2; 
    __m64 vec1, vec2, res; 

    vec1 = _mm_set_pi16(n1, n1, n1, n1); 
    vec2 = _mm_set_pi16(n2, n2, n2, n2); 

    res = _mm_add_pi16(vec1, vec2); 

    printf("%u %u %u %u \n", vec1[0], vec1[1], vec1[2], vec1[3]); 
    printf("%u %u %u %u \n", vec2[0], vec2[1], vec2[2], vec2[3]); 
    printf("%u %u %u %u \n", res[0], res[1], res[2], res[3]); 
} 

तरह इंटेल intrinsics उपयोग करने के लिए कोशिश कर रहा हूँ, लेकिन अजीब बात यह है कि मैं इस परिणाम मिल रहे हैं:

327685 327685 131074 131074 
131074 131074 458759 458759 
458759 458759 327685 327685 

मैं उपयोग कर रहा हूँ ग्रहण ग्रहण ... और मैं mmintrin.h, xmmintrin.h, emmintrin.h समेत हूं।

कृपया कोई व्याख्या कर सकते हैं कि इस

+1

आप शायद का उपयोग करना चाहिए '__m128i' SSE नए कोड में वैक्टर, नहीं 64 बिट MMX

निम्नलिखित कोड नमूना देखें। एसएसई 2 समर्थन 32-बिट कोड में भी बेसलाइन के रूप में मानने के लिए बहुत सुरक्षित है, और x86-64 के लिए इसकी गारंटी है। –

उत्तर

5

__m64 संदर्भण के रूप में सरणी गैर-मानक है।
मुझे नहीं पता कि आपका कंपाइलर इसे कैसे संभालता है।
मैं विजुअल स्टूडियो में इंटेल कंपाइलर का उपयोग कर रहा हूं, और एक संकलन त्रुटि प्राप्त कर रहा हूं। आपको प्रिंटिंग से पहले एमएमएक्स रजिस्टर से एएलयू रजिस्टर में uint16 तत्व निकालना चाहिए।
मूल्य निकालने के लिए _mm_extract_pi16 आंतरिक का उपयोग करें।

फ़ंक्शन से बाहर निकलने से पहले _mm_empty() आंतरिक फ़ंक्शन को कॉल करना न भूलें।

#include <stdint.h> 
#include <stdio.h> 

#include <mmintrin.h> 
#include <xmmintrin.h> 
#include <emmintrin.h> 

static void Test() 
{ 
    uint16_t n1=5; 
    uint16_t n2=2; 
    __m64 vec1,vec2,res; 

    vec1 = _mm_set_pi16 (n1 ,n1 ,n1 ,n1); 
    vec2 = _mm_set_pi16 (n2 ,n2 ,n2 ,n2); 

    res = _mm_add_pi16 (vec1, vec2); 

    //uint16_t res0 = _mm_extract_pi16(res, 0); 
    //uint16_t res1 = _mm_extract_pi16(res, 1); 
    //uint16_t res2 = _mm_extract_pi16(res, 2); 
    //uint16_t res3 = _mm_extract_pi16(res, 3); 

    printf("%u %u %u %u \n",_mm_extract_pi16(vec1, 0),_mm_extract_pi16(vec1, 1),_mm_extract_pi16(vec1, 2),_mm_extract_pi16(vec1, 3)); 
    printf("%u %u %u %u \n",_mm_extract_pi16(vec2, 0),_mm_extract_pi16(vec2, 1),_mm_extract_pi16(vec2, 2),_mm_extract_pi16(vec2, 3)); 
    printf("%u %u %u %u \n",_mm_extract_pi16(res, 0),_mm_extract_pi16(res, 1),_mm_extract_pi16(res, 2),_mm_extract_pi16(res, 3)); 

    _mm_empty(); 
} 

int main() 
{ 
    Test(); 

    return 0; 
} 

आउटपुट::

 
5 5 5 5 
2 2 2 2 
7 7 7 7 
+1

आईआईआरसी, एबीआई को एफपीयू को फ़ंक्शन कॉल पर x87 स्थिति में होना आवश्यक है। इसलिए आपको printf को कॉल करने से पहले '_mm_empty()' होना चाहिए। अप्रचलित MMX के बजाय एसएसई का उपयोग करते हुए ओपी को यह समस्या नहीं होगी। –

+0

एमएमएक्स 90 के दशक से संबंधित है, आपको एसएसई का उपयोग करना होगा ... भले ही यह अकादमिक उद्देश्य के लिए है ... कृपया एसएसई का उपयोग करें !!! – Rotem

3

साथ कुछ गड़बड़ है का हेक्साडेसिमल तार करने के लिए उन मूल्यों को परिवर्तित करते हैं:

0x00050005 0x00050005 0x00020002 0x00020002 
0x00020002 0x00020002 0x00070007 0x00070007 
0x00070007 0x00070007 0x00050005 0x00050005 

ऐसा लगता है कि संकलक एक subscripted __m64 चर करने के लिए हमेशा की तरह अभिन्न प्रोन्नति आवेदन नहीं है, इसलिए कि आपके द्वारा पारित प्रत्येक मान पैरामीटर स्पेस के 16 बिट (शायद स्टैक पर) का उपभोग कर रहा है, और फिर printf प्रत्येक %u के लिए 32 बिट्स डीकोड कर रहा है।

आप की तरह स्पष्ट डाले के साथ इसे ठीक करने में सक्षम होना चाहिए:

printf("%u %u %u %u \n", (unsigned int)vec1[0], (unsigned int)vec1[1], 
         (unsigned int)vec1[2], (unsigned int)vec1[3]); 

इंटीग्रल प्रोन्नति variadic कार्यों के मापदंडों को लागू किया जा करने वाले हैं ... लेकिन अगर यहां subscripting का परिणाम वास्तव में एक नहीं है अभिन्न प्रकार के, तो वह नियम अब लागू नहीं होता है।

+0

तो, मैं इसे कैसे ठीक कर सकता हूं? कोई उपाय ? समस्या ** _ mm_set_pi8 ** और ** _ mm_add_pi16 ** के साथ समान है, लेकिन यह 32 –

+0

@ एनेची के लिए काम कर रही है: समस्या केवल प्रदर्शन के लिए 'printf()' के मानों को पास करने में है ... गणनाएं हो रही हैं सही किया। आप सटीक प्रकार 'printf() 'चाहता है पर कास्ट करके प्रदर्शन को ठीक कर सकते हैं। –

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