Questa è la prima volta che lavoro con gli intrinseca SSE. Sto cercando di convertire un semplice pezzo di codice in una versione più veloce utilizzando Intel SSE intrinseco (fino a SSE4.2). Mi sembra di incontrare un numero di errori.Ottimizzazione del codice tramite Intel SSE intrinseca per la vettorizzazione
La versione scalare del codice è: (semplice moltiplicazione di matrici)
void mm(int n, double *A, double *B, double *C)
{
int i,j,k;
double tmp;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) {
tmp = 0.0;
for(k = 0; k < n; k++)
tmp += A[n*i+k] *
B[n*k+j];
C[n*i+j] = tmp;
}
}
Questa è la mia versione: Ho incluso #include
void mm_sse(int n, double *A, double *B, double *C)
{
int i,j,k;
double tmp;
__m128d a_i, b_i, c_i;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) {
tmp = 0.0;
for(k = 0; k < n; k+=4)
a_i = __mm_load_ps(&A[n*i+k]);
b_i = __mm_load_ps(&B[n*k+j]);
c_i = __mm_load_ps(&C[n*i+j]);
__m128d tmp1 = __mm_mul_ps(a_i,b_i);
__m128d tmp2 = __mm_hadd_ps(tmp1,tmp1);
__m128d tmp3 = __mm_add_ps(tmp2,tmp3);
__mm_store_ps(&C[n*i+j], tmp3);
}
}
Dove sto andando di sbagliato in questo? Sto ottenendo diversi errori come questo:
mm_vec.c (84): errore: un valore di tipo "int" non può essere assegnato ad un'entità di tipo "__m128d" A_i = __mm_load_ps (& A [n * i + k]);
questo è come mi sto la compilazione: ICC -O2 mm_vec.c -o vec
qualcuno può aiutare me convertire questo codice in modo accurato. Grazie!
UPDATE:
secondo i vostri suggerimenti, mi hanno fatto le seguenti modifiche:
void mm_sse(int n, float *A, float *B, float *C)
{
int i,j,k;
float tmp;
__m128 a_i, b_i, c_i;
for(i = 0; i < n; i++)
for(j = 0; j < n; j++) {
tmp = 0.0;
for(k = 0; k < n; k+=4)
a_i = _mm_load_ps(&A[n*i+k]);
b_i = _mm_load_ps(&B[n*k+j]);
c_i = _mm_load_ps(&C[n*i+j]);
__m128 tmp1 = _mm_mul_ps(a_i,b_i);
__m128 tmp2 = _mm_hadd_ps(tmp1,tmp1);
__m128 tmp3 = _mm_add_ps(tmp2,tmp3);
_mm_store_ps(&C[n*i+j], tmp3);
}
}
Ma ora mi sembra di essere sempre un errore di segmentazione. Lo so forse perché non sto accedendo correttamente agli indici di array per gli array A, B, C. Sono molto nuovo a questo e non sono sicuro di come procedere con questo.
Si prega di aiutarmi a determinare l'approccio corretto verso la gestione di questo codice.
Sto lavorando con ICC non GCC. Pensi che gestirlo in questo modo: a_i = _mm_load_ps (& A [n * i + k]); è l'approccio corretto? Gli esempi che vedo pubblicati altrove (anche sulla documentazione Intel Intrinsic) hanno esempi molto semplici. le matrici A, B, C sono state tutte allocate con malloc. – PGOnTheGo
@Hello_PG Il carico non è direttamente sbagliato. Non è comunque necessario caricare c_i. Per la maggior parte ICC ha le stesse estensioni di gcc - penso che sia il caso di quello di allineamento, ho più familiarità con GCC che con ICC personalmente, quindi mi sono qualificato con quello e ho collegato i documenti che sapevo come trovare. malloc non garantisce l'allineamento adatto su tutte le piattaforme, quindi posix_memalign è probabilmente necessario. L'affermazione che ho suggerito fallire? – Flexo
Quando provo ad allocare memoria per A in questo modo: A = (float *) _ aligned_malloc (dimensione * dimensione * sizeof (float), 16); Ricevo un errore di compilazione: riferimento indefinito a 'aligned_malloc 'con icc. questo è come sto la compilazione: ICC -O2 mm_vec.c -o vec2 – PGOnTheGo