Nein, das ist nicht garantiert. Wenn Sie einen NETLIB BLAS ohne Optimierungen verwenden, stimmen die Ergebnisse größtenteils überein. Für jede praktische Anwendung von BLAS und LAPACK wird jedoch ein hochoptimiertes paralleles BLAS verwendet. Die Parallelisierung bewirkt, auch wenn sie nur in den Vektorregistern einer CPU parallel arbeitet, dass sich die Reihenfolge, in der die einzelnen Terme ausgewertet werden, und die Reihenfolge der Summierung ändert. Nun folgt aus der fehlenden assoziativen Eigenschaft im IEEE-Standard, dass die Ergebnisse nicht gleich sind. Genau das, was Sie erwähnt haben, kann passieren.
In der NETLIB BLAS ist das Skalarprodukt nur eine um den Faktor 5 abgewickelte for-Schleife:
DO I = MP1,N,5
DTEMP = DTEMP + DX(I)*DY(I) + DX(I+1)*DY(I+1) +
$ DX(I+2)*DY(I+2) + DX(I+3)*DY(I+3) + DX(I+4)*DY(I+4)
END DO
und es liegt an dem Compiler, ob jede Multiplikation sofort zu DTEMP hinzugefügt wird oder ob alle 5 Komponenten zuerst aufsummiert werden und dann zu DTEMP hinzugefügt werden. In OpenBLAS handelt es sich je nach Architektur um einen komplizierteren Kernel:
__asm__ __volatile__
(
"vxorpd %%ymm4, %%ymm4, %%ymm4 \n\t"
"vxorpd %%ymm5, %%ymm5, %%ymm5 \n\t"
"vxorpd %%ymm6, %%ymm6, %%ymm6 \n\t"
"vxorpd %%ymm7, %%ymm7, %%ymm7 \n\t"
".align 16 \n\t"
"1: \n\t"
"vmovups (%2,%0,8), %%ymm12 \n\t" // 2 * x
"vmovups 32(%2,%0,8), %%ymm13 \n\t" // 2 * x
"vmovups 64(%2,%0,8), %%ymm14 \n\t" // 2 * x
"vmovups 96(%2,%0,8), %%ymm15 \n\t" // 2 * x
"vmulpd (%3,%0,8), %%ymm12, %%ymm12 \n\t" // 2 * y
"vmulpd 32(%3,%0,8), %%ymm13, %%ymm13 \n\t" // 2 * y
"vmulpd 64(%3,%0,8), %%ymm14, %%ymm14 \n\t" // 2 * y
"vmulpd 96(%3,%0,8), %%ymm15, %%ymm15 \n\t" // 2 * y
"vaddpd %%ymm4 , %%ymm12, %%ymm4 \n\t" // 2 * y
"vaddpd %%ymm5 , %%ymm13, %%ymm5 \n\t" // 2 * y
"vaddpd %%ymm6 , %%ymm14, %%ymm6 \n\t" // 2 * y
"vaddpd %%ymm7 , %%ymm15, %%ymm7 \n\t" // 2 * y
"addq $16 , %0 \n\t"
"subq $16 , %1 \n\t"
"jnz 1b \n\t"
...
Dadurch wird das Skalarprodukt in kleine Skalarprodukte der Länge 4 aufgeteilt und summiert.
Bei Verwendung der anderen typischen BLAS-Implementierungen wie ATLAS, MKL, ESSL, ... bleibt dieses Problem gleich, da jede BLAS-Implementierung unterschiedliche Optimierungen verwendet, um schnellen Code zu erhalten. Aber meines Wissens braucht man ein künstliches Beispiel, um wirklich fehlerhafte Ergebnisse zu erzielen.
Wenn es notwendig ist, dass die BLAS-Bibliothek für die gleichen Ergebnisse zurückgibt (bitweise gleich), muss eine reproduzierbare BLAS-Bibliothek verwendet werden, wie zum Beispiel: