SIMD: регистрирует изменение значения во время выполнения

Так что в моем коде в данный момент происходит что-то странное, речь идет о следующем регистре __m256i local, присвоенном при вычислении где-то, а также __m256i mask, который не имеет отношения к локальному.

Где выполняется следующее:

  std::cout << _mm256_extract_epi32 (local, 0) << ", " << _mm256_extract_epi32(local,1) << ", " << _mm256_extract_epi32(local,2) << ", " << _mm256_extract_epi32(local,3) << ", " << _mm256_extract_epi32(local,4) << ", " << _mm256_extract_epi32(local,5) << ", " << _mm256_extract_epi32(local,6) << ", " << _mm256_extract_epi32(local,7) << std::endl;

  for (int l = 0; l < 8; ++l)
  {
    if (mask[l]) mask[l] = 0; else mask[l] = 1;
  }
  std::cout << _mm256_extract_epi32 (local, 0) << ", " << _mm256_extract_epi32(local,1) << ", " << _mm256_extract_epi32(local,2) << ", " << _mm256_extract_epi32(local,3) << ", " << _mm256_extract_epi32(local,4) << ", " << _mm256_extract_epi32(local,5) << ", " << _mm256_extract_epi32(local,6) << ", " << _mm256_extract_epi32(local,7) << std::endl;`

Я получаю 519, 519, 519, 519, 519, 519, 519, 519 для первого вывода и 0, 0, 0, 0, 0, 0, 0, 0 для второго, хотя они взяты из одного и того же регистра. Любая идея, как что-то подобное могло произойти?


person Philippe    schedule 25.01.2018    source источник
comment
Это не минимально воспроизводимый пример, поскольку в нем отсутствуют определения для local и mask, в том числе то, как эти переменные получают свои значения.   -  person 1201ProgramAlarm    schedule 25.01.2018


Ответы (1)


Является ли целью вашего цикла for доступ к 32-битным словам в 256-битном векторе mask? Это не правильный способ сделать это. Когда вы используете оператор нижнего индекса для доступа к mask, компилятор выходит за пределы местоположения фактической переменной mask в памяти и затирает последующую 7x 256-байтовую область, следующую за ней.

Если вы хотите легко получить доступ к 32-битным словам в mask, попробуйте объявить его как:

union vec8x32_t
{
  __m256i  vector;
  uint32_t words[8];
};

vec8x32_t mask;

Затем вы можете сделать так:

// Do some AVX thing with mask:
mask.vector = _mm256_set_epi32(0, 1, 0, 1, 0, 1, 0, 1);

// Manipulate the components of mask:
for (int l = 0; l < 8; ++l)
{
  if (mask.words[l]) mask.words[l] = 0; else mask.words[l] = 1;
}
person toojays    schedule 25.01.2018
comment
Код OP в том виде, в котором он представлен, не будет компилироваться. Если вы посмотрите на определение для __m256i (оно находится в <immintrin.h>), вы увидите, что это уже союз, и ваш союз не нужен. - person 1201ProgramAlarm; 25.01.2018
comment
@ 1201ProgramAlarm, похоже, это зависит от компилятора. Я вижу это определение в MSVC 2015, но GCC 7 его не предоставляет, жалуясь: error: request for member ‘m256i_u32’ in ‘mask’, which is of non-class type ‘__m256i {aka __vector(4) long long int}’. - person toojays; 25.01.2018
comment
Тогда GCC не использует для них стандартные заголовки Intel. Вздох. - person 1201ProgramAlarm; 25.01.2018