I haben eine ausgerichtete Reihe von ganzen Zahlen in einem Speicher enthalten Indizes I0, I1, I2, I3. Mein Ziel ist es, sich in ein __m256i Register zu erhalten, enthaltend I 0, I 0 + 1, I1, I1 + 1, I2, I2 + 1, I3, I3 + 1. Der schwierige Teil ist sie in die 256-Bit-Register als I0 bekommen, I0 , I1, I1, I2, I2, I3, I3, nach dem ich einfach ein Register hinzufügen kann, das 0, 1, 0, 1, 0, 1, 0, 1 enthält.AVX2 Wie Effizientes Vier Ganze Zahlen laden zu Selbst-Indizes eines 256-Bit-Register und kopieren Odd-Indizes?
Ich fand die intrinsische, _mm256_castsi128_si256, die Lassen Sie mich die 4 ganzen Zahlen in die unteren 128 Bits des 256-Bit-Registers laden, aber ich habe Mühe, die besten von dort zu verwendenden Eigenarten zu finden.
Jede Hilfe wäre willkommen. Ich habe Zugriff auf alle SSE-Versionen, AVX und AVX2 und möchte dies nur mit Intrinsics tun.
Edit:
Ich denke, das funktioniert, aber ich bin nicht, wie effizient es ist ... in dem Prozess der Prüfung.
// _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: Der obige Code funktioniert nicht, weil _mm256_unpacklo_epi32 nicht so, wie ich dachte verhält. Der obige Code führt zu I0, I0 + 1, I1, I1 + 1, I0, I0 + 1, I1, I1 + 1.
Edit3: Der folgende Code funktioniert, wieder obwohl ich nicht sicher bin, ob es am effizientesten ist:
__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);