Saya membaca pertanyaan yang sangat menarik ini di Stack Overflow:
Salah satu komentar mengatakan:
"Tidak ada artinya sama sekali di Haswell, throughput FP multiply dua kali lipat dari FP add. Itu karena kedua port 0 dan 1 dapat digunakan untuk multiply, tetapi hanya port 1 yang dapat digunakan untuk penambahan. Karena itu, Anda dapat menipu dengan menyatu -multiply menambahkan karena kedua port dapat melakukannya. "
Mengapa mereka memungkinkan dua kali lebih banyak perkalian simultan dibandingkan dengan penambahan?
cpu
computer-architecture
alu
floating-point
intel
pengguna1271772
sumber
sumber
Jawaban:
Ini mungkin menjawab judul pertanyaan, jika bukan badan:
Penambahan titik apung memerlukan penyejajaran dua mantissa sebelum menambahkannya (tergantung pada perbedaan antara kedua eksponen), yang berpotensi membutuhkan sejumlah besar pergeseran sebelum penambah. Kemudian diperlukan renormalisasi hasil penambahan mantissa, yang berpotensi membutuhkan sejumlah besar variabel shift untuk memformat hasil floating point dengan benar. Dengan demikian, dua pemindah laras mantissa berpotensi membutuhkan lebih banyak gerbang penundaan, penundaan kawat lebih besar, atau siklus tambahan yang melebihi penundaan ujung depan multiplier pengangkut carry-adder-tree yang dipadatkan dengan baik.
Ditambahkan untuk OP: Perhatikan bahwa menambahkan panjang 2 milimeter dan 2 kilometer bukanlah 4 unit. Itu karena kebutuhan untuk mengkonversi satu atau pengukuran lain ke skala yang sama atau representasi unit sebelum penambahan. Konversi itu pada dasarnya memerlukan penggandaan dengan kekuatan 10. Hal yang sama biasanya perlu terjadi selama penambahan floating point, karena angka floating point adalah bentuk bilangan bulat berskala bervariasi (mis. Ada unit atau faktor skala, eksponen, yang terkait dengan setiap nomor). Jadi, Anda mungkin perlu skala salah satu angka dengan kekuatan 2 sebelum menambahkan bit mantissa mentah agar keduanya mewakili unit atau skala yang sama. Penskalaan ini pada dasarnya adalah bentuk sederhana dari perkalian dengan kekuatan 2. Dengan demikian, penambahan titik apung membutuhkan perkalian(yang, sebagai kekuatan 2, dapat dilakukan dengan bit shift variabel atau barrel shifter, yang dapat membutuhkan kabel yang relatif panjang dalam kaitannya dengan ukuran transistor, yang dapat relatif lambat dalam rangkaian sub-mikron-litografi yang dalam). Jika kedua nomor tersebut sebagian besar dibatalkan (karena yang satu hampir negatif dari yang lain), maka mungkin ada kebutuhan untuk mengubah skala hasil penambahan serta untuk memformat hasil yang sesuai. Jadi penambahan bisa lambat jika lebih jauh lagi membutuhkan 2 penggandaan (pra dan pasca) langkah-langkah yang mengelilingi penambahan biner dari jumlah baku tetap (terbatas) dari bit mantissa yang mewakili satuan atau skala yang setara, karena sifat format angka (titik mengambang IEEE ).
Ditambahkan # 2: Juga, banyak tolok ukur bobot FMACS (gandakan-terakumulasi) lebih dari sekadar menambahkan. Dalam MAC berfusi, penyelarasan (shift) dari addend sering dapat sebagian besar dilakukan secara paralel dengan multiply, dan add mantissa sering dapat dimasukkan dalam pohon CSA sebelum propagasi carry final.
sumber
Dalam multiplikasi FP, pemrosesan eksponen ternyata merupakan penambahan sederhana (untuk alasan yang persis sama bahwa penggandaan dalam domain log hanyalah penambahan). Anda telah menemukan logaritma, saya harap.
Sekarang perhatikan betapa sulitnya menambahkan dua angka dalam bentuk logaritmik ...
Floating point mendiami area abu-abu antara domain linier dan log, dengan aspek keduanya. Setiap nomor FP terdiri dari eksponen mantissa (yang linear) dan (logaritmik). Untuk menentukan arti setiap bit dalam mantissa, Anda harus terlebih dahulu melihat eksponen (yang hanya merupakan faktor skala).
Dalam penambahan FP, pemrosesan eksponen dalam kasus umum, memerlukan pergantian barel mantissa dua kali, di mana setiap pergantian barel secara efektif merupakan kasus khusus dari perkalian yang sedikit disederhanakan.
(Pergeseran pertama menyelaraskan kedua input ke kekuatan yang sama 2, sehingga bit mantissa memiliki bobot biner yang sama di setiap operan.
Contoh desimal akan cukup (meskipun biner jelas digunakan) ...
Yang kedua skala output ...
Jadi secara paradoks, penambahan FP melibatkan sesuatu seperti dua perkalian yang harus dilakukan secara berurutan, dengan penambahan mantissa di antara keduanya. Dalam terang itu, kinerja yang dilaporkan tidak begitu mengejutkan.
sumber
TL: DR : karena Intel berpikir SSE / AVX FP menambahkan latensi lebih penting daripada throughput, mereka memilih untuk tidak menjalankannya pada unit FMA di Haswell / Broadwell.
Haswell menjalankan (SIMD) FP berkembang biak pada unit eksekusi yang sama dengan FMA ( Fused Multiply-Add ), yang memiliki dua karena beberapa kode intensif-FP dapat menggunakan sebagian besar FMA untuk melakukan 2 FLOPs per instruksi. Latensi 5 siklus yang sama dengan FMA, dan seperti
mulps
pada CPU sebelumnya (Sandybridge / IvyBridge). Haswell menginginkan 2 unit FMA, dan tidak ada kerugian untuk membiarkan multiply berjalan baik karena mereka latensi yang sama dengan unit multiply dedikasi pada CPU sebelumnya.Tetapi itu membuat unit tambahan SIMD FP khusus dari CPU sebelumnya tetap berjalan
addps
/addpd
dengan latensi 3 siklus. Saya telah membaca bahwa alasan yang mungkin mungkin adalah bahwa kode yang banyak FP tambahkan cenderung menghambat latensi, bukan throughput. Itu tentu benar untuk jumlah yang naif dari array dengan hanya satu (vektor) akumulator, seperti yang sering Anda dapatkan dari GCC auto-vectorizing. Tetapi saya tidak tahu apakah Intel secara terbuka mengkonfirmasi bahwa itu alasan mereka.Broadwell adalah sama ( tetapi mempercepat
mulps
/mulpd
ke latensi 3c sementara FMA tetap di 5c). Mungkin mereka bisa memintas unit FMA dan mengeluarkan hasil penggandaan sebelum melakukan dummy add0.0
, atau mungkin sesuatu yang sangat berbeda dan itu terlalu sederhana. BDW sebagian besar adalah die-shrink dari HSW dengan sebagian besar perubahan kecil.Dalam Skylake, semua FP (termasuk penambahan) berjalan pada unit FMA dengan latensi 4 siklus dan throughput 0.5c, kecuali tentu saja div / sqrt dan bitwise booleans (mis. Untuk nilai absolut atau negasi). Intel tampaknya memutuskan bahwa itu tidak bernilai silikon tambahan untuk menambah FP latensi yang lebih rendah, atau bahwa
addps
throughput yang tidak seimbang bermasalah. Dan juga standardisasi latensi membuat menghindari konflik write-back (ketika 2 hasil siap dalam siklus yang sama) lebih mudah untuk dihindari dalam penjadwalan uop. yaitu menyederhanakan penjadwalan dan / atau penyelesaian port.Jadi ya, Intel memang mengubahnya dalam revisi mikroarsitektur utama berikutnya (Skylake). Mengurangi latensi FMA dengan 1 siklus menjadikan manfaat unit tambahan SIMD FP khusus jauh lebih kecil, untuk kasus yang terikat latensi.
Skylake juga menunjukkan tanda-tanda Intel bersiap-siap untuk AVX512, di mana memperluas penambah SIMD-FP terpisah hingga lebar 512 bit akan membuat lebih banyak daerah mati. Skylake-X (dengan AVX512) dilaporkan memiliki inti yang hampir identik dengan klien Skylake biasa, kecuali untuk cache L2 yang lebih besar dan (dalam beberapa model) unit FMA 512-bit tambahan "dibaut" ke port 5.
SKX mematikan ALU SIMD port 1 ketika 512-bit uops sedang dalam penerbangan, tetapi perlu cara untuk mengeksekusi
vaddps xmm/ymm/zmm
di titik mana pun. Ini menjadikan unit FP ADD khusus pada port 1 menjadi masalah, dan merupakan motivasi terpisah untuk perubahan dari kinerja kode yang ada.Fakta menyenangkan: segala sesuatu dari Skylake, KabyLake, Coffee Lake, dan bahkan Cascade Lake secara mikro identik dengan Skylake, kecuali Cascade Lake menambahkan beberapa instruksi AVX512 baru. IPC tidak berubah sebaliknya. CPU yang lebih baru memiliki iGPU yang lebih baik. Ice Lake (Sunny Cove microarchitecture) adalah pertama kalinya dalam beberapa tahun kami melihat mikroarsitektur baru yang sebenarnya (kecuali Danau Cannon yang tidak pernah dirilis secara luas).
Argumen berdasarkan kompleksitas unit FMUL vs unit FADD menarik tetapi tidak relevan dalam kasus ini . Unit FMA mencakup semua perangkat keras yang diperlukan untuk melakukan penambahan FP sebagai bagian dari FMA 1 .
Catatan: Maksud saya
fmul
instruksi x87 , maksud saya SSU / AVX SIMD / skalar FP multipel ALU yang mendukung 32-bit single-precision /float
dan 64-bitdouble
precision (53-bit significantand alias mantissa). misalnya instruksi sepertimulps
ataumulsd
. 80-bit x87 yangfmul
sebenarnya masih hanya throughput 1 / jam di Haswell, pada port 0.CPU modern memiliki lebih dari cukup transistor untuk melempar pada masalah ketika itu layak , dan ketika itu tidak menyebabkan masalah keterlambatan propagasi jarak fisik. Terutama untuk unit eksekusi yang hanya aktif beberapa waktu. Lihat https://en.wikipedia.org/wiki/Dark_silicon dan makalah konferensi 2011 ini: Gelap Silikon dan Akhir dari Multicore Scaling. Inilah yang memungkinkan CPU memiliki throughput FPU yang besar, dan throughput integer yang besar, tetapi tidak keduanya sekaligus (karena unit eksekusi yang berbeda berada pada port pengiriman yang sama sehingga mereka saling bersaing). Dalam banyak kode yang disetel dengan hati-hati yang tidak menghambat bandwidth, itu bukan unit eksekusi back-end yang merupakan faktor pembatas, tetapi sebaliknya throughput instruksi front-end. ( core lebar sangat mahal ). Lihat juga http://www.lighterra.com/papers/modernmicroprocessors/ .
Sebelum Haswell
Sebelum HSW , CPU Intel seperti Nehalem dan Sandybridge memiliki SIMD FP multiply pada port 0 dan SIMD FP menambahkan pada port 1. Jadi ada unit eksekusi terpisah dan throughput seimbang. ( https://stackoverflow.com/questions/8389648/how-do-i-achieve-the-theoretical-maximum-of-4-flops-per-cycle
Haswell memperkenalkan dukungan FMA ke dalam CPU Intel (beberapa tahun setelah AMD memperkenalkan FMA4 di Bulldozer, setelah Intel memalsukannya dengan menunggu selambat-lambatnya untuk mengumumkan kepada publik bahwa mereka akan mengimplementasikan FMA 3-operan, bukan 4-operan bukan -Destructive-destination FMA4). Fakta menyenangkan: AMD Piledriver masih merupakan CPU x86 pertama dengan FMA3, sekitar setahun sebelum Haswell pada Juni 2013
Ini memerlukan beberapa peretasan besar internal untuk bahkan mendukung satu uop dengan 3 input. Tapi bagaimanapun, Intel melakukan yang terbaik dan mengambil keuntungan dari transistor yang terus menyusut untuk memasukkan dua unit FMA SIMD 256-bit, membuat Haswell (dan penggantinya) binatang buas untuk matematika FP.
Target kinerja yang mungkin dimiliki Intel adalah produk BLAS matmul dan vector dot yang padat. Keduanya kebanyakan dapat menggunakan FMA dan tidak perlu hanya menambahkan.
Seperti yang saya sebutkan sebelumnya, beberapa beban kerja yang melakukan sebagian besar atau hanya penambahan FP dihambat pada add latency, (kebanyakan) bukan throughput.
Catatan Kaki 1 : Dan dengan pengali
1.0
, FMA secara harfiah dapat digunakan sebagai tambahan, tetapi dengan latensi yang lebih buruk daripadaaddps
instruksi. Ini berpotensi berguna untuk beban kerja seperti menjumlahkan array yang panas di cache L1d, di mana FP menambahkan throughput lebih penting daripada latensi. Ini hanya membantu jika Anda menggunakan beberapa akumulator vektor untuk menyembunyikan latensi, tentu saja, dan mempertahankan 10 operasi FMA dalam unit eksekusi FP (5c latensi / 0,5c throughput = 10 operasi latensi * produk bandwidth). Anda perlu melakukannya saat menggunakan FMA untuk produk titik vektor juga .Lihat David Kanter menulis tentang mikroarsitektur Sandybridge yang memiliki diagram blok dimana EU berada di mana port untuk NHM, SnB, dan keluarga AMD Bulldozer. (Lihat juga tabel instruksi Agner Fog dan panduan microarch optimasi asm, dan juga https://uops.info/ yang juga memiliki pengujian eksperimental untuk uops, port, dan latency / throughput dari hampir setiap instruksi pada banyak generasi di mikroarsitektur Intel.)
Juga terkait: https://stackoverflow.com/questions/8389648/how-do-i-achieve-the-theoretical-maximum-of-4-flops-per-cycle
sumber
[cpu-architecture]
,[performance]
,[x86-64]
,[assembly]
, dan[sse]
. Saya menulis jawaban pada kode C ++ untuk menguji dugaan Collatz lebih cepat dari perakitan tulisan tangan - mengapa? yang menurut banyak orang bagus. Juga ini tentang eksekusi pipeline OoO.Saya akan melihat bagian ini:
"Mengapa mereka mengizinkan " ...
TL; DR - karena mereka mendesainnya seperti itu. Itu adalah keputusan manajemen. Tentu ada jawaban mantissa dan bit shifters, tetapi ini adalah hal-hal yang masuk ke dalam keputusan manajemen.
Mengapa mereka mendesainnya seperti itu? Jawabannya adalah bahwa spesifikasi dibuat untuk memenuhi tujuan tertentu. Sasaran itu termasuk kinerja dan biaya. Performa tidak diarahkan pada operasi, melainkan tolok ukur seperti FLOPS atau FPS dalam Crysis.
Tolok ukur ini akan memiliki campuran fungsi, beberapa di antaranya dapat diproses secara bersamaan.
Jika perancang mencari yang memiliki dua fungsi widget A membuatnya lebih cepat, daripada dua fungsi widget B, maka mereka akan pergi dengan widget A. Menerapkan dua A dan dua B akan lebih mahal.
Melihat ke belakang ketika superscalar dan pipa super (sebelum multi-core) pertama kali menjadi umum pada chip komersial, ini ada di sana untuk meningkatkan kinerja. Pentium memiliki dua pipa, dan tidak ada vektor yang menyatukan. Haswell memiliki lebih banyak pipa, unit vektor, pipa yang lebih dalam, fungsi khusus, dan banyak lagi. Mengapa tidak ada semuanya? Karena mereka mendesainnya seperti itu.
sumber
Diagram dari Intel ini dapat membantu:
Tampaknya mereka telah memberi FMA setiap unit (pengganda tambah-pengganda) serta pengganda dan satu penambah. Mereka mungkin atau mungkin tidak berbagi perangkat keras di bawahnya.
Pertanyaan tentang mengapa jauh lebih sulit untuk dijawab tanpa dasar-dasar desain internal, tetapi teks dalam kotak ungu memberi kita petunjuk dengan "doubles peak FLOPs": prosesor akan menargetkan serangkaian tolok ukur, yang berasal dari kasus penggunaan aktual. FMA sangat populer di dalamnya karena ini adalah unit dasar dari perkalian matriks. Selain itu kurang populer.
Anda dapat, seperti telah ditunjukkan, menggunakan kedua port untuk melakukan penambahan dengan dengan instruksi FMA di mana parameter perkalian adalah 1, menghitung (A x 1) + B. Ini akan sedikit lebih lambat daripada penambahan yang telanjang.
sumber
Mari kita lihat langkah-langkah yang memakan waktu:
Tambahan: Sejajarkan eksponen (mungkin operasi shift besar-besaran). Satu penambah 53 bit. Normalisasi (hingga 53 bit).
Perkalian: Satu jaringan penambah besar untuk mengurangi 53 x 53 produk satu bit dengan jumlah dua angka 106 bit. Satu penambah 106 bit. Normalisasi. Saya akan mengatakan mengurangi produk bit menjadi dua angka dapat dilakukan secepat penambah akhir.
Jika Anda dapat membuat waktu multiplikasi variabel maka Anda memiliki keuntungan bahwa normalisasi hanya akan bergeser satu bit sebagian besar waktu, dan Anda dapat mendeteksi kasus-kasus lain dengan sangat cepat (input dinormalisasi, atau jumlah eksponen terlalu kecil).
Sebagai tambahan, perlu langkah-langkah normalisasi sangat umum (menambahkan angka yang tidak berukuran sama, mengurangi angka yang dekat). Jadi untuk perkalian, Anda dapat memiliki jalur cepat dan menerima pukulan besar untuk jalur lambat; sebagai tambahan kamu tidak bisa.
PS. Membaca komentar: Masuk akal bahwa menambahkan angka yang dinormalisasi tidak menyebabkan penalti: Ini hanya berarti bahwa di antara bit yang digeser untuk menyelaraskan eksponen, banyak yang nol. Dan hasil yang dinormalisasi berarti bahwa Anda berhenti bergeser untuk menghapus nol terkemuka jika itu akan membuat eksponen terlalu kecil.
sumber
-ffast-math
menetapkan FTZ / DAZ (denush flush ke nol) untuk melakukan itu alih-alih mengambil bantuan FP.