Saya mengerti bahwa --ffast-math
flag gcc dapat sangat meningkatkan kecepatan untuk float ops, dan melampaui standar IEEE, tetapi sepertinya saya tidak dapat menemukan informasi tentang apa yang sebenarnya terjadi saat diaktifkan. Adakah yang bisa menjelaskan beberapa detail dan mungkin memberikan contoh yang jelas tentang bagaimana sesuatu akan berubah jika bendera dihidupkan atau dimatikan?
Saya memang mencoba menggali SO untuk pertanyaan serupa tetapi tidak dapat menemukan apa pun yang menjelaskan cara kerja matematika cepat.
double
, tetapi bervariasi tergantung pada aplikasi). Satu hal yang perlu diperhatikan adalah optimisasi ffast-matematika tidak serta merta menambahkan "lebih". Satu-satunya alasan mengapa itu tidak sesuai dengan IEEE adalah karena jawabannya berbeda (walaupun sedikit) dari apa yang tertulis.x
lebih kecil dari 10, kesalahan dalam contoh Mystical akan turun sekitar 10 ^ -10. Tetapi jikax = 10e20
, kesalahannya mungkin jutaan.-fassociative-math
yang termasuk dalam-funsafe-math-optimizations
yang pada gilirannya diaktifkan dengan-ffast-math
Mengapa tidak GCC mengoptimalkana*a*a*a*a*a
ke(a*a*a)*(a*a*a)
?-ffast-math
tidak lebih dari sekedar melanggar kepatuhan IEEE yang ketat.Pertama-tama, tentu saja, itu benar- benar melanggar kepatuhan IEEE, memungkinkan misalnya penataan ulang instruksi untuk sesuatu yang secara matematis sama (idealnya) tetapi tidak persis sama di floating point.
Kedua, ini menonaktifkan pengaturan
errno
setelah fungsi matematika instruksi tunggal, yang berarti menghindari penulisan ke variabel thread-lokal (ini dapat membuat perbedaan 100% untuk fungsi-fungsi pada beberapa arsitektur).Ketiga, itu membuat asumsi bahwa semua matematika terbatas , yang berarti bahwa tidak ada pemeriksaan untuk NaN (atau nol) dibuat di tempat di mana mereka akan memiliki efek yang merugikan. Secara sederhana diasumsikan bahwa ini tidak akan terjadi.
Keempat, ini memungkinkan pendekatan timbal balik untuk pembagian dan akar kuadrat resiprokal.
Lebih jauh lagi, ia menonaktifkan ditandatangani nol (kode menganggap nol ditandatangani tidak ada, bahkan jika target mendukungnya) dan pembulatan matematika, yang memungkinkan antara lain lipat konstan pada waktu kompilasi.
Terakhir, ini menghasilkan kode yang mengasumsikan bahwa tidak ada gangguan hardware yang dapat terjadi karena pensinyalan / penjebakan matematika (yaitu, jika ini tidak dapat dinonaktifkan pada arsitektur target dan akibatnya terjadi , mereka tidak akan ditangani).
sumber
-ffast-math
Set -fno-math-errno, -funsafe-math-optimization, -finite-math-only, -fno-rounding-matematika, -fno-signaling -nans dan -fcx-limited-range. Opsi ini menyebabkan makro preprocessor FAST_MATH didefinisikan. "dan sesuatu dari glibc, seperti (math.h
near math_errhandling)" Secara default semua fungsi mendukung errno dan penanganan pengecualian. Dalam mode matematika cepat gcc dan jika fungsi sebaris didefinisikan, ini mungkin tidak benar. "-ffast-math
memungkinkan kompiler untuk memotong beberapa sudut dan melanggar beberapa janji (seperti yang dijelaskan), yang secara umum tidak berbahaya seperti itu dan bukan masalah bagi kebanyakan orang. Bagi kebanyakan orang, itu sama, hanya lebih cepat. Namun, jika kode Anda mengasumsikan dan mengandalkan janji-janji ini, maka kode Anda mungkin berperilaku berbeda dari yang Anda harapkan. Biasanya, ini berarti bahwa program akan tampak berfungsi dengan baik, sebagian besar, tetapi beberapa hasil mungkin "tidak terduga" (katakanlah, dalam simulasi fisika, dua objek mungkin tidak bertabrakan dengan benar).-O2
umumnya memungkinkan "setiap" optimasi hukum, kecuali yang bertukar ukuran untuk kecepatan.-O3
juga memungkinkan optimasi yang memperdagangkan ukuran untuk kecepatan. Itu masih mempertahankan kebenaran 100%.-ffast-math
mencoba untuk membuat operasi matematika lebih cepat dengan memungkinkan perilaku "sedikit salah" yang biasanya tidak berbahaya, tetapi akan dianggap salah oleh kata-kata standar. Jika kode Anda memang jauh berbeda dalam kecepatan pada dua kompiler (tidak hanya 1-2%) maka periksa bahwa kode Anda benar-benar sesuai standar dan ...#pragma omp parallel for
, dan di dalam lingkaran Anda membaca dan menulis ke alamat yang ditunjukkan oleh argumen fungsi, dan melakukan percabangan yang tidak sepele. Sebagai dugaan yang tidak berpendidikan, Anda mungkin meronta-ronta cache dari dalam invokasi yang ditentukan oleh implementasi Anda, dan MSVC mungkin secara keliru menghindari toko perantara yang diamanatkan oleh aturan alias. Mustahil untuk diceritakan.