Ранее я использовал операторы SIMD для повышения эффективности своего кода, однако сейчас я сталкиваюсь с новой ошибкой, которую не могу устранить. Для этой задачи скорость имеет первостепенное значение.
Размер массива не будет известен до тех пор, пока данные не будут импортированы, и может быть очень маленьким (100 значений) или огромным (10 миллионов значений). В последнем случае код работает нормально, однако я сталкиваюсь с ошибкой, когда использую меньше 130036 значений массива.
Кто-нибудь знает, что вызывает эту проблему и как ее решить?
Я приложил (проверенный) код, который будет использоваться позже в более сложной функции. Ошибка происходит в «arg1List [i] = …»
#include <iostream>
#include <xmmintrin.h>
#include <emmintrin.h>
void main()
{
int j;
const int loop = 130036;
const int SIMDloop = (int)(loop/4);
__m128 *arg1List = new __m128[SIMDloop];
printf("sizeof(arg1List)= %d, alignof(Arg1List)= %d, pointer= %p", sizeof(arg1List), __alignof(arg1List), arg1List);
std::cout << std::endl;
for (int i = 0; i < SIMDloop; i++)
{
j = 4*i;
arg1List[i] = _mm_set_ps((j+1)/100.0f, (j+2)/100.0f, (j+3)/100.0f, (j+4)/100.0f);
}
}
Выравнивание является причиной.
MOVAPS — перемещение выровненных упакованных значений с плавающей запятой одинарной точности
[…] Операнд должен быть выровнен по 16-байтовой границе, иначе будет сгенерировано исключение общей защиты (#GP).
Вы можете увидеть, что проблема исчезла, как только вы выровняете указатель:
__m128 *arg1List = new __m128[SIMDloop + 1];
arg1List = (__m128*) (((int) arg1List + 15) & ~15);
Других решений пока нет …