Bir "flop" un aynı anakronistik tanımına göre flop sayısını saymak yerine, FPU'nun kodunuzun ne kadar bağlı olduğunu veya FPU'yu ne kadar etkili kullandığınızı değerlendirmenin bir yolunu istediğiniz gibi görünüyor. Diğer bir deyişle, her bir kayan nokta birimi her döngüde tam kapasitede çalışıyorsa aynı pik değerine ulaşan bir metrik istersiniz. Bunun nasıl olabileceğini görmek için Intel Sandy Bridge'e bakalım.
Donanım destekli kayan nokta işlemleri
Bu çip AVX talimatlarını destekler , bu nedenle kayıtlar 32 bayt uzunluğundadır (4 çift tutma). Süperskalar mimari, talimatların üst üste gelmesine izin verir, çoğu aritmetik talimatın tamamlanması birkaç döngü sürer, ancak bir sonraki döngüde yeni bir talimat başlayabilir. Bu anlambilim genellikle gecikme / ters verim yazılarak kısaltılır, 5/2 değeri, komutun tamamlanması için 5 döngü süreceği anlamına gelir, ancak her iki döngüde yeni bir talimat başlatabilirsiniz (işlenenlerin mevcut olduğu varsayılarak) bağımlılık ve hafıza beklememek).
Çekirdek başına üç kayan nokta aritmetik birimi vardır, ancak üçüncüsü tartışmamızla ilgili değildir, ilgili iki A ve M birimini çağıracağız çünkü birincil işlevleri toplama ve çarpmadır. Örnek talimatlar (bkz. Agner Sis tabloları )
vaddpd
: paketlenmiş ekleme, 1 döngü için işgal ünitesi A, gecikme / ters verim 3/1
vmulpd
: paketlenmiş çarpma, ünite M, 5/1
vmaxpd
: paketlenmiş maksimum çift seçimi, birim A, 3/1
vdivpd
: paketli bölme, birim M (ve bazı A), girişe bağlı olarak 21/20 - 45/44
vsqrtpd
: paketlenmiş kare kök, bazı A ve M, girişe bağlı olarak 21/21 ila 43/43
vrsqrtps
: tek duyarlıklı giriş için paketlenmiş düşük hassasiyetli karşılıklı karekök (8 floats
)
Örtüşebilir ne için kesin semantik vdivpd
ve vsqrtpd
görünüşte ince ve AFAIK, her yerde belgelenmiştir değil. Çoğu kullanımda, bence çakışma olasılığı çok azdır, ancak kılavuzdaki ifadeler birden çok iş parçacığının bu talimatta çakışma için daha fazla olasılık sunabileceğini düşündürmektedir. Her döngüde vaddpd
ve vmulpd
her döngüde toplam 8 flop için zirve floplarına vurabiliriz . Yoğun matris-matris çarpımı ( dgemm
) bu zirveye makul bir şekilde yaklaşabilir.
Özel talimatlar için flopları sayarken, FPU'nun ne kadarının işgal edildiğine bakarım. Diyelim ki, girdi aralığınızda vdivpd
, tamamıyla işgal eden M birimini tamamlamak için ortalama 24 döngü sürdüğünü, ancak (varsa) eklenti döngülerin yarısı boyunca eşzamanlı olarak gerçekleştirilebileceğini iddia edin. FPU, bu döngüler sırasında 24 paketlenmiş çarpan ve 24 paketli ekleme gerçekleştirebilir (mükemmel bir şekilde serpiştirilmiş vaddpd
ve vmulpd
), ancak a ile vdivpd
yapabileceğimiz en iyisi 12 ek paket ekidir. Bölme işleminin mümkün olan en iyi yolunun donanımı (makul) kullanmak olduğunu varsayarsak, vdivpd
her bir skaler bölünmeyi 36 "flop" olarak saymamız gerektiğini belirten 36 paketli "flop" olarak sayabiliriz.
Karşılıklı kare kök ile, özellikle tam doğruluk gerekli değilse veya giriş aralığı darsa, bazen donanımı yenmek mümkündür. Yukarıda belirtildiği gibi, vrsqrtps
talimat çok ucuzdur, bu nedenle (tek hassasiyette ise) vrsqrtps
temizlemek için bir veya iki Newton yinelemesi yapabilirsiniz. Bu Newton iterasyonları sadece
y *= (3 - x*y*y)*0.5;
Bu işlemlerin çoğunun yapılması gerekiyorsa, bu naif değerlendirmeden önemli ölçüde daha hızlı olabilir y = 1/sqrt(x)
. Donanım yaklaşık karşılıklı karekökü bulunmadan önce, performansa duyarlı bazı kodlar Newton yinelemesi için bir ilk tahmin bulmak için rezil tamsayı işlemleri kullanıyordu.
Kütüphane tarafından sağlanan matematik fonksiyonları
Benzer bir buluşsal yöntem kütüphane tarafından sağlanan matematik işlevlerine de uygulanabilir. SSE talimatlarının sayısını belirlemek için profil oluşturabilirsiniz, ancak tartıştığımız gibi, bu tüm hikaye değildir ve tüm zamanını özel işlevleri değerlendirerek geçiren bir program zirveye yaklaşmış gibi görünebilir, bu doğru olabilir, ancak FPU üzerindeki kontrolünüz dışında her zaman harcandığını söylemek için kullanışlı değil.
Temel olarak iyi bir vektör matematik kütüphanesi kullanmanızı öneririm (örneğin Intel'in VML'si, MKL'nin bir parçası). Her çağrı için döngü sayısını ölçün ve bu döngü sayısı üzerinden elde edilebilecek en yüksek floplarla çarpın. Dolayısıyla, paketlenmiş bir üstel değerlendirmek için 50 döngü alırsa, kayıt genişliğinin 100 flop katı olarak sayın. Ne yazık ki, vektör matematik kitaplıklarını aramak bazen zor ve tüm özel işlevlere sahip değilsiniz, bu nedenle skaler matematik yapabilirsiniz, bu durumda varsayımsal skalerimizi 100 flop olarak üstel sayabilirsiniz (muhtemelen hala 50 sürer) Bu nedenle, yalnızca bu üstel değerleri değerlendirmek için her zaman harcanırsa "zirvenin"% 25'ini elde edersiniz).
Diğerlerinin de belirttiği gibi, PAPI veya çeşitli arabirimleri kullanarak döngüleri ve donanım olay sayaçlarını sayabilirsiniz. Basit çevrim sayımı için çevrim sayacını rdtsc
, bir satır içi montaj snippet'i ile talimatı kullanarak doğrudan okuyabilirsiniz .