Как умножить матрицы с помощью SSE?

Задача - перемножить 2 массива float'ов с помощью SSE.
В каждом массиве 4 элемента.
Код:
//перемножить a на b, xyz - исходные данные
float xyz[] = {0.1, 0.3 ,0.5};
alignas(16) float a[] = {116.0,500.0,200.0,1.0};
alignas(16) float b[] = {Y(xyz),(X(xyz)-Y(xyz)),Y(xyz)-Z(xyz),1};
__m128* a_simd = reinterpret_cast<__m128*>(a);
__m128* b_simd = reinterpret_cast<__m128*>(b);

size_t size = sizeof(float);
void *ptr = aligned_alloc(32,N * size);
float* c = reinterpret_cast<float*>(ptr);
size_t i = 0;
while (i<N/2){
            _mm_store_ps(c, _mm_mul_ps(*a_simd, *b_simd));
            i++;
            a_simd++;
            b_simd++;
            c += 4;
 }

Если вывести значения c, то они будут некорректными.
  • Вопрос задан
  • 260 просмотров
Решения вопроса 1
@nagayev Автор вопроса
Нашел на stackoverflow:
https://stackoverflow.com/questions/26494785/timin...
Вместо стандартного ключевого слова alignas в С до 11 версии и старом С++ можно использовать
__attribute__((aligned(16)))
в GCC, а в MSVC аналогичный decltype.
Решение (перемножение массивов a и b и сохранение результат в c):
float a[n];
float b[n];
alignas(16) float с[n] ; // массив хранения результата
__m128 x,y,result; // тип данных для хранения SSE регистра 
result = _mm_setzero_ps(); // обнуляем регистр
for(int k = 0; k <= (n-4); k += 4) {
            x = _mm_load_ps(&a[k]); // Загружаем 4 float'а
            y = _mm_load_ps(&b[k]);
            result = _mm_mul_ps(x,y); // умножаем
            _mm_store_ps(&c[k],result); // сохраняем результат в c
}
int extra = n%4; // Если размер не кратен 4, то домножаем остаток
if(extra!=0) {
            for(i = (n-extra); i < n; i++) {
                c[i] = a[i] * b[i];
            }
 }
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы