Bilimsel yazılım, neyin ayarlanması gerektiğini bilmek kadar, diğer yazılımlardan çok da farklı değildir.
Kullandığım yöntem rastgele duraklatmadır . İşte benim için buldukları bazı hızlandırmalar:
Eğer log
ve gibi fonksiyonlarda çok fazla zaman harcanıyorsa, exp
bu fonksiyonların argümanlarının ne olduğunu, çağrılan noktaların bir fonksiyonu olarak görebiliyorum. Genellikle aynı argümanla tekrar tekrar çağırılırlar. Eğer öyleyse, notlama büyük bir hızlandırma faktörü üretir.
BLAS veya LAPACK işlevlerini kullanıyorsam, dizileri kopyalamak, matrisleri çarpmak, choleski dönüşümü vb. İşlemleri yapmak için rutinlerde çok fazla zaman harcandığını bulabilirim.
Dizileri kopyalama yordamı hız için orada değil, kolaylık olması için orada. Bunu yapmanın daha az kullanışlı, ancak daha hızlı bir yolu olduğunu görebilirsiniz.
Matrisleri çarpma ya da ters çevirme ya da choleski dönüşümü alma rutinleri, üst ya da alt üçgen için 'U' ya da 'L' gibi seçenekleri belirten karakter argümanlarına sahip olma eğilimindedir. Yine, bunlar kolaylık için oradalar. Benim bulduğum şey, matrislerimin çok büyük olmadığından, rutinler zamanlarının yarısından fazlasını harcayarak alt rutini arayarak karakterleri sadece seçenekleri deşifre etmek için harcıyorlardı . En pahalı matematik rutinlerinin özel amaçlı versiyonlarını yazmak, büyük bir hızlanma üretti.
Sadece ikincisini genişletebilirsem: matrix-multiply rutin DGEMM, karakter argümanlarının kodunu çözmek için LSAME öğesini çağırır. Kapsayıcı yüzde zamanına bakmak (bakmaya değer tek istatistik) profilerler "iyi" olarak kabul edilen DGEMM'ye toplam zamanın yüzde bir kısmını (% 80 gibi) ve LSAME'yi toplam zamanın% 50'sini kullanarak gösterebilir. Birincisine bakarsak, "iyi bir şekilde optimize edilmesi gerekiyor, bu konuda yapabileceğim pek bir şey yok" demeye özendirilirsiniz. İkincisine baktığınızda, "Huh? Bunların hepsi bu mu? Bu sadece ufacık bir küçük rutin. Bu profiler yanlış olmalı!"
Yanlış değil, sadece bilmeniz gerekenleri söylemiyor. Rasgele duraklatmanın gösterdiği şey DGEMM'in yığın örneklerinin% 80'inde ve LSAME'in% 50'de olduğu. (Bunu tespit etmek için çok fazla örneğe ihtiyacınız yok. 10 genellikle bol miktarda.) Dahası, bu örneklerin çoğunda, DGEMM LSAME'yi birkaç farklı kod satırından çağırıyor .
Şimdi her iki rutinin neden bu kadar kapsayıcı zaman geçirdiğini biliyorsunuz . Bunca zaman geçirmek için kodunuzda nerelerden çağrıldığını da biliyorsunuz . Bu yüzden rastgele duraklama kullanıyorum ve ne kadar iyi olursa olsun, profilleyicilere sarılıklı bir bakış atıyorum. Neler olduğunu anlatmak yerine ölçüm almakla daha çok ilgileniyorlar.
Matematik kütüphanesi yordamlarının ilk dereceye kadar optimize edildiğini varsaymak kolaydır, ancak gerçekte çok çeşitli amaçlar için kullanılabilir olması için optimize edilmiştir. Neler olduğunu gerçekten görmelisin , varsayılması kolay olanı değil.
EKLENDİ: Son iki sorunuzu cevaplamak için:
İlk denenecek en önemli şeyler nelerdir?
10-20 yığın örneği alın ve yalnızca özetlemeyin, her birinin size ne söylediğini anlayın. Bunu önce, son ve aralarında yapın. ("Denemek" yok, genç Skywalker.)
Ne kadar performans alabileceğimi nasıl bilebilirim?
Yığın örnekleri , zamanın kesirinin ne kadar tasarruf edileceğine dair çok kaba bir tahmin verecektir. (Bu, bir dağılımını izler ; burada , neyi düzelteceğinizi görüntüleyen örnek sayısıdır ve , toplam örnek sayısıdır. Bunu değiştirmek için kullandığınız kodun maliyeti, ki bu umarım küçük olacaktır.) Ardından, hız oranı ve bu büyük olabilir. Bunun matematiksel olarak nasıl davrandığına dikkat edin. Eğer ve , ortalama ve mod 2 bir hızlanma oranı için 0.5, İşte dağıtım bulunuyor:
Eğer riskten daha sonra ise, evet var küçük olasılık (0,03%) oβ ( s + 1 , ( n - s ) + 1 ) s n 1 / ( 1 - x ) n = 10 s = 5 x x xxβ( s + 1 , ( n - s ) + 1 )sn1/(1−x)n=10s=5x
x % 11'den daha düşük bir hız için 0,1'den düşüktür. Ancak bu, 10'dan büyük bir hızlanma oranı için 0.9'dan büyük olması eşit bir olasılıktır . Program hızıyla orantılı olarak para alıyorsanız, bu kötü bir ihtimal değil.x
Daha önce de belirttiğim gibi, daha fazla yapamayana kadar tüm prosedürü tekrarlayabilirsiniz ve bileşik hızlanma oranı oldukça büyük olabilir.
EKLENDİ: Pedro'nun yanlış pozitiflerle ilgili endişesine cevap olarak, ortaya çıkmaları beklenebilecek bir örnek oluşturmaya çalışmama izin verin. İki veya daha fazla kez görmedikçe asla potansiyel bir problem üzerinde hareket etmeyiz, bu nedenle bir problemi gördüğümüzde, özellikle toplam örnek sayısı büyük olduğunda, yanlış pozitiflerin bir problemi gördüğümüzde olmasını beklerdik. Diyelim ki 20 örnek aldık ve iki kez görelim. Bu, maliyetinin, tahminin şekli olan toplam yürütme süresinin% 10 olduğunu tahmin ediyor. (Dağılımın ortalaması daha yüksektir - .) Aşağıdaki grafikteki alt eğri dağılımı:(s+1)/(n+2)=3/22=13.6%
40 örneğe kadar numune aldığımızı (bir seferde sahip olduğumdan daha fazla) ve sadece ikisinde bir sorun görüp görmediğimizi düşünün. Bu problemin tahmini maliyeti (modu), uzun boylu eğride gösterildiği gibi% 5'tir.
"Yanlış pozitif" nedir? Bir sorunu çözdüğünüzde, beklenenden daha küçük bir kazanç olduğunu fark edersiniz, çözdüğünüz için pişman olursunuz. Eğriler (eğer sorun "küçükse), kazanım onu gösteren örneklerin oranından daha az olabilse de, ortalama olarak daha büyük olacağını göstermektedir.
Çok daha ciddi bir risk var - "yanlış bir negatif". Bir sorun olduğunda o zaman, ama bulunamadı. (Buna katkıda bulunmak, kanıt yokluğunun yokluğun kanıtı olarak değerlendirilme eğiliminde olduğu "onaylama yanlılığı" dır.)
Ne bir profil (iyi bir) almak sorun gerçekte ne hakkında daha az kesin bilgi pahasına, çok daha hassas bir ölçüm (yanlış pozitif dolayısıyla daha az şans) olsun olduğunu (bulma ve alma dolayısıyla daha az şans herhangi bir kazanç). Bu, elde edilebilecek genel hızlanmayı sınırlar.
Profil oluşturucuların kullanıcılarının gerçekte pratikte gördükleri hızlandırma faktörlerini bildirmelerini teşvik ediyorum.
Yeniden yapılması gereken başka bir nokta var. Pedro'nun sahte pozitifler hakkındaki sorusu.
Yüksek derecede optimize edilmiş koddaki küçük sorunlara inerken bir zorluk olabileceğinden bahsetti. (Bana göre küçük bir problem, toplam sürenin% 5'ini veya daha azını ilgilendiren bir problemdir.)
% 5 dışında tamamen optimal bir program inşa etmek tamamen mümkün olduğu için, bu noktaya sadece bu cevapta olduğu gibi deneysel olarak değinilebilir . Deneysel deneyimlerden genellemek için, şöyle devam eder:
Bir program, yazıldığı gibi, genellikle optimizasyon için çeşitli fırsatlar içerir. (Onlara "problemler" diyebiliriz, ancak bunlar genellikle mükemmel kodlardır, sadece önemli ölçüde iyileştirme yeteneğine sahiptirler.) Bu şemada biraz zaman alan yapay bir program gösteriliyor (100s, diyelim) ve A, B, C, ... bulunup düzeltildiğinde, orijinal 100'lerin% 30,% 21, vb.
F sorununun orijinal zamanın% 5'ine mal olduğuna, bu nedenle "küçük" olduğuna ve 40 veya daha fazla örnek olmadan bulmanın zor olduğuna dikkat edin.
Bununla birlikte, ilk 10 örnek kolayca A problemini bulur. ** Bu düzeltildiğinde, program 100/70 = 1.43x'lik bir hızlanma için sadece 70s alır. Bu sadece programı daha hızlı kılmakla kalmamakta, aynı zamanda kalan sorunların aldığı yüzdeleri de büyütmektedir. Örneğin, B problemi başlangıçta toplamın% 21'i olan 21'i aldı, ancak A, B'yi çıkardıktan sonra 70'lerden 21'i, veya% 30'u alır, bu yüzden tüm işlemin tekrarlandığını bulmak daha kolaydır.
İşlem beş kez tekrarlandıktan sonra, uygulama süresi 16.8'dir, bunun dışında F problemi% 30'dur,% 5'tir, bu nedenle 10 örnek bunu kolayca bulur.
Demek istediğim bu. Ampirik olarak, programlar büyüklük dağılımına sahip bir dizi problem içerir ve bulunan ve çözülen herhangi bir problem kalanları bulmayı kolaylaştırır. Bunu başarmak için, sorunlardan hiçbiri atlanamaz, çünkü, eğer oradalarsa, orada oturup, zaman içinde toplam hızı sınırlandırır ve kalan sorunları büyütmede başarısız olurlar.
Bu yüzden saklanmakta olan sorunları bulmak çok önemlidir .
Eğer A'dan F'ye problemler bulunur ve giderilirse, hızlanma 100 / 11,8 = 8,5x olur. Bunlardan biri kaçırılırsa, örneğin D, o zaman hızlanma sadece 100 / (11.8 + 10.3) = 4.5x olur.
Yanlış negatifler için ödenen bedel bu.
Bu yüzden, profilci "burada önemli bir sorun yok gibi gözüküyor" derken (yani iyi kodlayıcı, bu pratik olarak en uygun koddur), belki de doğru ve belki de değildir. ( Yanlış bir negatif .) Başka bir profilleme yöntemi denemeden ve orada olduğunu keşfetmediğiniz sürece, daha yüksek hız için düzeltmek için daha fazla sorun olup olmadığından emin olamazsınız. Tecrübelerime göre, profilleme yönteminin özetlenmiş çok sayıda örneğe ihtiyacı yoktur, özetlenir, ancak her bir örneğin optimizasyon için herhangi bir fırsat tanımak için yeterince iyi anlaşıldığı az sayıda örnek vardır.
2/0.3=6.671 - pbinom(1, numberOfSamples, sizeOfProblem)
1 - pbinom(1, 20, 0.3) = 0.9923627
xβ(s+1,(n−s)+1)nsy1/(1−x)xyy−1BetaPrime dağılımı. Bu davranışa ulaşarak 2 milyon örnekle simüle ettim:
distribution of speedup
ratio y
s, n 5%-ile 95%-ile mean
2, 2 1.58 59.30 32.36
2, 3 1.33 10.25 4.00
2, 4 1.23 5.28 2.50
2, 5 1.18 3.69 2.00
2,10 1.09 1.89 1.37
2,20 1.04 1.37 1.17
2,40 1.02 1.17 1.08
3, 3 1.90 78.34 42.94
3, 4 1.52 13.10 5.00
3, 5 1.37 6.53 3.00
3,10 1.16 2.29 1.57
3,20 1.07 1.49 1.24
3,40 1.04 1.22 1.11
4, 4 2.22 98.02 52.36
4, 5 1.72 15.95 6.00
4,10 1.25 2.86 1.83
4,20 1.11 1.62 1.31
4,40 1.05 1.26 1.14
5, 5 2.54 117.27 64.29
5,10 1.37 3.69 2.20
5,20 1.15 1.78 1.40
5,40 1.07 1.31 1.17
(n+1)/(n−s)s=ny
Bu, hızlanma faktörlerinin ve bunların araçlarının, 5, 4, 3 ve 2 numuneden 2 vuruş için dağılımının bir grafiğidir. Örneğin, 3 örnek alınırsa ve bunlardan 2'si bir soruna isabet ederse ve bu sorun giderilebiliyorsa, ortalama hızlandırma faktörü 4x olur. 2 isabet sadece 2 örnekte görülürse, ortalama hız belirsizdir - kavramsal olarak sonsuz döngülü programlar sıfır olmayan bir olasılıkla var olur!