Tidak, itu tidak dijamin. Jika Anda menggunakan NETLIB BLAS tanpa optimasi apa pun, sebagian besar hasilnya benar-benar sama. Tetapi untuk penggunaan praktis BLAS dan LAPACK, orang menggunakan BLAS paralel yang sangat dioptimalkan. Paralelisasi menyebabkan, bahkan jika itu hanya bekerja secara paralel di dalam register vektor CPU, bahwa urutan bagaimana istilah tunggal dievaluasi berubah dan urutan penjumlahan juga berubah. Sekarang mengikuti bentuk properti asosiatif yang hilang dalam standar IEEE bahwa hasilnya tidak sama. Jadi persis hal yang Anda sebutkan bisa terjadi.
Dalam NETLIB BLAS produk skalar hanya untuk loop yang tidak digerakkan oleh faktor 5:
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
dan terserah kompiler jika setiap perkalian ditambahkan ke DTEMP segera atau jika semua 5 komponen dirangkum terlebih dahulu dan kemudian ditambahkan ke DTEMP. Di OpenBLAS tergantung pada arsitektur kernel yang lebih rumit:
__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"
...
yang membagi produk skalar menjadi produk skalar kecil dengan panjang 4 dan menjumlahkannya.
Menggunakan implementasi BLAS khas lainnya seperti ATLAS, MKL, ESSL, ... masalah ini tetap sama karena setiap implementasi BLAS menggunakan optimisasi yang berbeda untuk mendapatkan kode cepat. Tapi sejauh yang saya tahu orang perlu contoh buatan untuk menyebabkan hasil yang benar-benar salah.
Jika perlu bahwa perpustakaan BLAS kembali untuk hasil yang sama (agak bijaksana sama) kita harus menggunakan perpustakaan BLAS yang dapat direproduksi seperti: