У меня ошибка сегментации, когда я пытаюсь использовать _mm_load_si128 в C для встроенных функций. Я видел, что данные должны быть выровнены по 16 бит, и что объединение делает это правильно. Но это не решает мою проблему.sse segfault на _mm_load_si128
#include <xmmintrin.h>
int main(void){
const int N = 8;
short int matrice1[] = {
10, 11, 12, 13, 14, 15, 16, 17,
20, 21, 22, 23, 24, 25, 26, 27,
30, 31, 32, 33, 34, 35, 36, 37,
40, 41, 42, 43, 44, 45, 46, 47,
50, 51, 52, 53, 54, 55, 56, 57,
60, 61, 62, 63, 64, 65, 66, 67,
70, 71, 72, 73, 74, 75, 76, 77,
80, 81, 82, 83, 84, 85, 86, 87
};
transpose_simd(matrice1, N);
return 0;
}
union Line{
short int* row;
__m128i sRow;
};
void transpose_simd(short int * matrice1, int N){
short int i, n, j;
union Line line1, line2; //matrix line
__m128i sLine1, sLine2; //sse version of the matrix line
__m128i sLine3, sLine4;
/*
There will be a loop surrounding the following code, but first I kept it simple
*/
// THE NEXT LINE GIVES A SEGMENTATION FAULT
sLine1 = _mm_load_si128((__m128i*) line1.row); //loads 1 matrix line (8 shorts of 16 bits = 128)
sLine2 = _mm_load_si128((__m128i*) line2.row);
sLine3 = _mm_unpackhi_epi16 (sLine1, sLine2); //shuffle the first 4 elements
sLine4 = _mm_unpackhi_epi16 (sLine1, sLine2); //shuffle the last 4 elements
_mm_store_si128((__m128i*)line1.row, sLine3);
_mm_store_si128((__m128i*)line2.row, sLine4);
}
Так что я получил решение из ответов. Он работает отлично после правильного осуществления двух циклов:
void transpose_simd(short int * matrice1, short int* matrice2, int N){
short int i=0, n=0;
short int* __attribute__ ((aligned (16))) line1; //ligne de matrice
short int* __attribute__ ((aligned (16))) line2;
__m128i sLine1, sLine2; //ligne en version sse
__m128i sLine3, sLine4;
/*
There will be a loop surrounding the following code, but first I kept it simple
*/
line1 = matrice1 + N*i;
line2 = matrice1 + N*(N/2 + i);
sLine1 = _mm_loadu_si128((__m128i*) line1); //charge 1 ligne (8 nombres de 16 bits = 128, "coup de bol")
sLine2 = _mm_loadu_si128((__m128i*) line2);
sLine3 = _mm_unpacklo_epi16 (sLine1, sLine2); //shuffle les 4 premiers chiffres de line1, voir p74
sLine4 = _mm_unpackhi_epi16 (sLine1, sLine2); //shuffle les 4 premiers chiffres de line1, voir p74
_mm_storeu_si128((__m128i*) (matrice2 + N*2*i), sLine3);
_mm_storeu_si128((__m128i*) (matrice2 + N*(2*i+1)), sLine4);
}
В основном, __attribute__ ((aligned (16)))
выравнивает свои переменные, так как объединение сохраняет смещение, но не устанавливает выравнивание. Кроме того, для большей безопасности используются несимметричные функции _mm_storeu_si128
и _mm_loadu_si128. Тем не менее, я не знаю, медленнее ли он, чем зависящая от версии версия этих методов.
Почему вы указываете * значение * строки 'line1.row' на указатель? Почему вы ожидаете, что это сработает? –
О, боже, ты прав. Я попробую это, как только вернусь на компьютер. – Vulpo
Я прекратил использовать союз, меня это смущало. Я выложу свой код за несколько минут. – Vulpo