В настоящее время я пишу хеш-таблицу, и один из моих тестов не прошел после изменения какой-либо реализации для использования векторных расширений. Оказывается, что когда у меня есть std :: array (я не знаю, проблема ли это в самом std :: array или что-то еще) и вставляю элементы в определенном порядке, мой код не работает. Но как только я меняю положение двух элементов, это неожиданно срабатывает. Элемент, о котором идет речь, равен 33, однажды изменившись на 17, код работает, как и ожидалось.
Я попытался посмотреть на скомпилированную сборку в godbolt, но моя сборка действительно недостаточно хороша, чтобы извлечь из этого полезную информацию. .
Я написал здесь пример минимально воспроизводимого кода:
#include <iostream>
#include <array>
#include <immintrin.h>
int main() {
// Dysfunctional order
std::array<std::uint32_t, 8> keys_not_functional = {{1,17,33,49,0,0,0,0}};
__m256i key_vector = _mm256_set1_epi32(33);
__m256i cmp_vector = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(keys_not_functional.data()));
__m256i cmp = _mm256_cmpeq_epi32(key_vector, cmp_vector);
std::uint8_t mask = _mm256_movemask_epi8(cmp);
if (mask != 0) {
std::uint8_t index = __builtin_ctz(mask) / 4;
std::cout << "Found at in dysfunctional: " << unsigned(index) << std::endl;
}
// Changing 17 and 33 makes this work without a problem
std::array<std::uint32_t, 8> keys_functional = {{1,33,17,49,0,0,0,0}};
key_vector = _mm256_set1_epi32(33);
cmp_vector = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(keys_functional.data()));
cmp = _mm256_cmpeq_epi32(key_vector, cmp_vector);
mask = _mm256_movemask_epi8(cmp);
if (mask != 0) {
std::uint8_t index = __builtin_ctz(mask) / 4;
std::cout << "Found at in functional: " << unsigned(index) << std::endl;
}
return 0;
}
Я скомпилировал его с: g++ -std=c++17 -mavx2 -march=native -O0
. Работает на g cc 7.4.0 в WSL1, Ubuntu 18.04.4 LTS, ядро 4.4.0-18362-Microsoft. Мой процессор - Kaby Lake R i5-8250.
Я еще не пробовал скомпилировать его в другой системе. Это проблема с моей конфигурацией / системой или даже с WSL? Может кто-нибудь указать мне причину этого?