मेरे पास इंडेक्स I0, I1, I2, I3 युक्त मेमोरी में पूर्णांक का एक गठबंधन सरणी है। मेरा लक्ष्य उन्हें I0, I0 + 1, I1, I1 + 1, I2, I2 + 1, I3, I3 + 1 युक्त __m256i रजिस्टर में प्राप्त करना है। कठिन हिस्सा उन्हें 256 बिट रजिस्टर में I0, I0 के रूप में प्राप्त कर रहा है , I1, I1, I2, I2, I3, I3, जिसके बाद मैं 0, 1, 0, 1, 0, 1, 0, 1.AVX2, 256 बिट रजिस्टर के सूचकांक और अजीब इंडेक्स में कॉपी करने के लिए चार इंटीग्रेट्स को कुशलतापूर्वक लोड कैसे करें?
में एक रजिस्टर जोड़ सकता हूं, मुझे आंतरिक, _mm256_castsi128_si256 मिला, जो कि मुझे 25 पूर्ण बिट रजिस्टर के निचले 128 बिट्स में 4 पूर्णांक लोड करने देता है, लेकिन मैं वहां से उपयोग करने के लिए सर्वोत्तम इंट्रिनिक्स खोजने के लिए संघर्ष कर रहा हूं।
किसी भी मदद की सराहना की जाएगी। मेरे पास सभी एसएसई संस्करणों, एवीएक्स, और एवीएक्स 2 तक पहुंच है और केवल इंट्रिनिक्स का उपयोग करके ऐसा करना चाहूंगा।
संपादित करें:
मैं इस काम करता है लगता है, लेकिन मैं इसे नहीं कैसे कुशल है ... यह परीक्षण करने की प्रक्रिया में हूँ।
// _mm128_load_si128: Loads 4 integer values into a temporary 128bit register.
// _mm256_broadcastsi128_si256: Copies 4 integer values in the 128 bit register to the low and high 128 bits of the 256 bit register.
__m256i tmpStuff = _mm256_broadcastsi128_si256 ((_mm_load_si128((__m128i*) indicesArray)));
// _mm256_unpacklo_epi32: Interleaves the integer values of source0 and source1.
__m256i indices = _mm256_unpacklo_epi32(tmpStuff, tmpStuff);
__m256i regToAdd = _mm256_set_epi32 (0, 1, 0, 1, 0, 1, 0, 1);
indices = _mm256_add_epi32(indices, regToAdd);
EDIT2: क्योंकि _mm256_unpacklo_epi32 तरह से मैंने सोचा था कि व्यवहार न करे इसके बाद के संस्करण कोड काम नहीं करता। उपरोक्त कोड के परिणामस्वरूप I0, I0 + 1, I1, I1 + 1, I0, I0 + 1, I1, I1 + 1 होगा।
Edit3: निम्नलिखित कोड काम करता है, हालांकि फिर से मुझे यकीन है कि अगर यह सबसे कारगर है नहीं कर रहा हूँ:
__m256i tmpStuff = _mm256_castsi128_si256(_mm_loadu_si128((__m128i*) indicesArray));
__m256i mask = _mm256_set_epi32 (3, 3, 2, 2, 1, 1, 0, 0);
__m256i indices= _mm256_permutevar8x32_epi32(tmpStuff, mask);
__m256i regToAdd = _mm256_set_epi32 (1, 0, 1, 0, 1, 0, 1, 0); // Set in reverse order.
indices= _mm256_add_epi32(indices, regToAdd);