Dies ist mein allererstes Arbeiten mit SSE-Intrinsics. Ich versuche, ein einfaches Stück Code in eine schnellere Version mit Intel SSE intrinsisch (bis SSE4.2) zu konvertieren. Ich scheine auf eine Reihe von Fehlern zu stoßen.Optimieren von Code mit Intel SSE-Intrinsics für die Vektorisierung
Die skalare Version des Codes ist: (einfache Multiplikation Matrix)
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;
}
}
Dies ist meine Version: Ich #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);
}
}
Wo enthalten sind, bin ich mit diesem schief gehen? Ich erhalte mehrere Fehler wie folgt aus:
mm_vec.c (84): Fehler: ein Wert vom Typ "int" kann nicht auf eine Entität vom Typ zugeordnet werden "__m128d" a_i = __mm_load_ps (& A [n * i + k]); Diese
ist, wie ich bin Kompilieren: icc -O2 mm_vec.c -o vec
Kann jemand bitte helfen Sie mir diesen Code genau zu konvertieren. Vielen Dank!
UPDATE:
Ihre Vorschläge nach, ich habe folgende Änderungen vorgenommen:
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);
}
}
Aber jetzt scheine ich einen Segmentation fault zu bekommen. Ich weiß das vielleicht, weil ich nicht richtig auf Array-Indizes für Array A, B, C zugreife. Ich bin sehr neu und weiß nicht, wie ich damit verfahren soll.
Bitte helfen Sie mir, den richtigen Umgang mit diesem Code zu bestimmen.
ich mit icc arbeite nicht gcc. Glauben Sie, dass es wie folgt Handhabung: a_i = _mm_load_ps (& A [n * i + k]), der richtige Ansatz ist? Die Beispiele, die ich an anderer Stelle (auch in der Intel Intrinsic-Dokumentation) gesehen habe, haben sehr einfache Beispiele. Die Arrays A, B, C wurden alle mit malloc zugeordnet. – PGOnTheGo
@Hello_PG Die Ladung selbst ist nicht direkt falsch. Sie müssen c_i jedoch nicht laden. Zum größten Teil ICC habe die gleichen Erweiterungen wie gcc - ich denke, das ist der Fall für die Ausrichtung ein, ich bin besser vertraut mit GCC als ICC persönlich obwohl so qualifizierte ich es mit, dass und auf die Dokumentation verknüpfen ich wusste, wie zu finden. malloc garantiert nicht die korrekte Ausrichtung auf allen Plattformen, daher wird wahrscheinlich posix_memign benötigt. Hat die von mir vorgeschlagene Behauptung versagt? – Flexo
Wenn ich versuche, wie dies für einen Speicher zuzuweisen: A = (float *) _ aligned_malloc (dimension * Maß * sizeof (float), 16); Ich bekomme einen Kompilierfehler: undefinierter Verweis auf 'aligned_malloc' mit icc. So kompiliere ich: icc -O2 mm_vec.c -o vec2 – PGOnTheGo