Выравнивание AVX в массиве

Я использую MSVC12 (Visual Studio 2013 Express) и пытаюсь реализовать быстрое умножение значений с плавающей запятой 8 * 8. Проблема заключается в выравнивании: вектор имеет на самом деле 9 * n значений, но мне всегда нужны только первые 8, так что, например. для n=0 гарантируется выравнивание по 32 байтам (когда я использую _mm_malloc), для n=1 "первое" значение выравнивается по 4*9 = 36 байт.

for(unsigned i = 0; i < n; i++) {
    float *coeff_set = (float *)_mm_malloc(909 * 100 *sizeof(float), 32);
    // this works for n=0, not n=1, n=2, ...
    __m256 coefficients = _mm256_load_ps(&coeff_set[9 * i]);
    __m256 result = _mm256_mul_ps(coefficients, coefficients);

    ...
}

Есть ли возможность это решить? Я хотел бы сохранить структуру своих данных, но если это невозможно, я бы изменил ее. Одно решение, которое я нашел, состояло в том, чтобы сначала скопировать 8 чисел с плавающей запятой в выровненный массив, а затем загрузить его, но тогда потеря производительности слишком высока.


person dommynik    schedule 29.07.2014    source источник
comment
Я думаю, вы имеете в виду i=0 и i=1, а не n. Что касается выравнивания, у вас действительно есть только несколько вариантов: либо дополнить структуру до 16 значений для сохранения выравнивания, либо использовать _mm256_loadu_ps для невыровненных нагрузок.   -  person Drew McGowen    schedule 29.07.2014
comment
Большое спасибо, что дали совет! Я не видел этого внутреннего! Код работает (и да, я имел в виду i, а не n.   -  person dommynik    schedule 29.07.2014
comment
Хорошо, я перенесу это в ответ.   -  person Drew McGowen    schedule 29.07.2014


Ответы (1)


У вас есть два варианта:

  1. Дополните каждый набор коэффициентов 16 значениями, чтобы сохранить выравнивание
  2. Используйте встроенную функцию _mm256_loadu_ps для невыровненного доступа

Первый вариант более эффективен с точки зрения скорости, а второй — более компактен.

person Drew McGowen    schedule 29.07.2014