Bilimsel yazılım ne kadar optimize edilmelidir?


13

Önemli hesaplama kaynakları gerektiren uygulamalar için, yüksek performans, bilimsel sonuçların verilmesi veya makul zamanda "kırılmaların" elde edilmesi söz konusu olduğunda kritik bir faktör olabilir.

Yazılım geliştiricileri bir uygulamayı optimize etmek için ne kadar zaman ve çaba harcamalıdır? Kullanılan anahtar kriterler nelerdir?


Bilim adamlarının yazdığı programlar genellikle çok uzun bir süre devam eder (örn. Simülasyonlar). Programcı zamanı ve bilgisayar çalışma süresi karşılaştırılabilir. Bu, günümüzün "olağan" programcı çalışmasından çok farklıdır. Hesaplamanın ilk günlerinde olduğu gibi, simülasyonu daha hızlı hale getirmek ve daha hızlı bitirmek ve işi daha hızlı yapmak için genellikle biraz çaba (ve programcı zamanı) yatırmaya değer.
Szabolcs

Yanıtlar:


15

Vakaların büyük çoğunluğunda, algoritmalardaki iyileştirmeler, optimizasyondaki iyileştirmeden daha büyük bir fark yaratır. Algoritmalar aynı zamanda düşük seviyeli optimizasyonlardan daha taşınabilirdir. Tavsiyem, önbellek yeniden kullanımı, aşırı kopyalardan veya iletişimden kaçınmak, dosya sistemine aklı başında davranmak ve kayan nokta çekirdeklerinin vektörleştirme için yeterli ayrıntı düzeyine sahip olmasını sağlamak için bellek düzeniyle ilgili en iyi uygulamaları takip etmektir. Bazen bu kabul edilebilir derecede yüksek bir "tepe" fraksiyonuna ulaşmak için yeterlidir (bu işlem için).

Önemli olduğunu düşündüğünüz (veya profilleyerek önemli olduğunu düşündüğünüz) işlemler için her zaman bir performans modeli çizin. Ardından, yüksek düzeyde ayarlanmış bir uygulamanın neler sunabileceğini tahmin etmek için performans modelini kullanabilirsiniz. Hızlandırmanın buna değer olduğuna karar verirseniz (yapabileceğiniz diğer şeylere göre), optimizasyonu yapın.

Belki de en zor zorluk, daha sonra API'yı değiştirmeye gerek kalmadan optimize edebilmeniz için yüksek seviyeli, önemli (bu kodlara çok sayıda kodun bağlı olacağı anlamında) arayüzler ve veri yapıları tasarlamaktır. Belirli optimizasyonların ve genel yönergelerin aksine, bunu deneyimler dışında nasıl öğreteceğimi bilmiyorum. Performansa duyarlı açık kaynaklı yazılımlarla çalışmak yardımcı olur. Herhangi bir API kararında olduğu gibi, sorun alanını anlamak önemlidir.


1
Son zamanlarda, analizimizin sınırlayıcı bir adımının çalışma zamanında 10.000 (en büyük olaylarımız için) iyileştirme faktörü aldım, sadece zaman ve mekanda O (n ^ 2) olan bir algoritmayı bir O (n log n ile değiştiriyorum) ) hem de.
Sanırım

1
Hızlandırma faktörleri (bir şeye göre), karşılaştırdıklarınızla net bir referansa değmez. Uygunsuz bir algoritmaya dayalı kötü bir uygulama ile karşılaştırırsanız ve sonra değişirseniz, o zaman büyük göreceli kazançlar beklemek mantıksız olmayacaktır.
Allan P. Engsig-Karup

1
@Allan: Tek bir değişiklikten elde etmek için 10.000 faktör vardı, o zaman açıkçası kötü seçilmiş bir uygulama oldu. Önceki kod, zaman karmaşıklığı kadar gereksiz alan tarafından yaralandı: önbellekleme performansı uçsuz bucaksızdı. Ama mesele bu değil mi?
dmckee --- eski moderatör kedi yavrusu

8

"Optimize et" i nasıl tanımlarsınız? Daha iyi algoritmaların veya hesaplama modellerinin geliştirilmesinden elle ayarlanmış birleştiricinin kullanılmasına kadar tüm bir spektrum vardır.

Benim düşünceme ve deneyime göre, düşük asılı meyve ortada bir yerde, örneğin altta yatan bilgisayar mimarisi için en uygun olan bir algoritma seçmek. Algoritmanın mutlaka yeni olması gerekmez ve temel mimariyi anlamanızın çok özel olması gerekmez, örn.

  • Mimarinizin SIMD'yi desteklediğini biliyorsanız, hesaplamayı işlemleriniz kısa vektörler olarak yazılabilecek şekilde yeniden yapılandırın,
  • Mimarinizin çok çekirdekli bir bilgisayar olduğunu biliyorsanız, hesaplama görevinizi birbirine müdahale etmeyen bireysel alt görevlere ayırmaya çalışın ve bunları paralel olarak çalıştırın (alt görevlerinizin bir DAG'sini düşünün) ,
  • Temel mimarinizin GPU'su varsa, hesaplamanızı kilit adımındaki verilerde yürüyen bir grup iş parçacığı olarak yeniden formüle etmenin yollarını düşünün,
  • vb...

Yukarıdaki tüm özelliklere, örneğin SIMD, paralellik ve GPU'ya, çok düşük seviyeli bilgi olmadan erişilebilir, ancak bunlardan kolayca yararlanabilen algoritmalarda sadece gerçekten bir avantaj sunar.


4

Şimdiye kadar ortaya atılan tüm cevapları kabul ediyorum ... Sadece kod optimizasyonunun gözden kaçan bir yönünü ele almak istiyorum: kalite beklentisi.

Kod optimizasyonu sorunu genellikle kullanıcı daha büyük ve daha büyük sorunları çözmeye çalıştığında ve kod kullanıcının ihtiyaçlarını / beklentilerini karşılamak için yetersiz olduğunda ortaya çıkar. Kod optimizasyonuna yatırım yapılması gereken süre, bu beklentiyi karşılama talebine bağlıdır. Rekabet avantajı için kritik bir ihtiyaç varsa (örneğin araştırmanızı diğerlerinden önce sıcak bir konuda bitirmek ve yayınlamak) kesinlikle önemli bir zaman ayırmaya değer.

Elbette, ne kadar zaman harcanması gerektiği, ne kadar hızlı olmanız gerektiğine ve kodun ne kadar taşınabilir olmasını istediğinize bağlıdır. Genellikle, bu iki ihtiyaç birbiriyle çatışır ve optimizasyona başlamadan önce hangisinin daha önemli olduğuna karar vermelisiniz. Ne kadar taşınabilir olursanız, kodda (algoritma / veri yapısı) üst düzey tasarım değişikliklerine o kadar güvenmeniz gerekir. Kodun daha hızlı çalışmasını istediğinizde, belirli bir makineye özgü düşük düzeyli optimizasyonlarla ayarlanması gerekir (örn. Kod / derleyici / çalışma zamanı optimizasyonları).


4

İcra hızını kazanmak için bu kadar çok ay (ve her zaman efsanevi :-)) harcamanın (maliyet) analizini yapmalısınız. Bu yazılım parçasının kaç kez kullanılacağını ve kaç kişi tarafından kazanıldığını tahmin edebilmeniz gerekir.

Temel kural, her zamanki gibi, ünlü 80/20 kuralıdır. Bir anda, birkaç yüzde (veya daha az) çalışma süresi kazanmak için daha fazla zaman harcamak artık yeterli değildir. Ama analiz etmeniz gerekecek.

Ve yukarıdaki posterlere içtenlikle katılıyorum: API'nızın iyi düşünülmüş olduğundan emin olun, böylece birçok değişikliğe ihtiyaç duymaz ve kodun taşınabilir ve sürdürülebilir olduğundan emin olun (yazdığınız bir algoritmayı ve nitty-gritty'yi yeniden analiz etmeyi düşünün on yıl önce optimize edildi). İyi programlama uygulamaları ve standart kütüphaneler kullandığınızdan emin olun. Şansı, başvurunuz için en verimli algoritma hakkında düşünülmüş birisidir.

Donald Knuth'dan alıntı yapmak için: "erken optimizasyon tüm kötülüklerin köküdür". Bu yüzden kodunuzu profil yapın, ancak çok yakında değil.


Pareto İlkesi (80/20) kuralından mı bahsediyorsunuz? Öyleyse, optimizasyon çabalarını yavaşlamanın% 80'ini oluşturan kodun% 20'sine odaklamamız gerektiği anlamına mı geliyor? Yoksa sadece% 20 hızlanma bekleyebilirseniz, optimize etmeye değmez mi demek istediniz?
Paul

Hayır, sadece bir tür ilke olarak kullandım, tam olarak 80/20 değil. Bir süre sonra, sadece birkaç yüzde kazanmak için o kadar çaba harcayacaksınız ki artık çabaya değmeyecek.
GertVdE

3

Bazı ek öneriler:

  1. Çalışan bir programda herhangi bir optimizasyon yapmadan önce, kodun bütünlüğünü korumaya yardımcı olan iyi bir dizi test vakası olduğundan emin olun. Yanlış sonuçları daha hızlı almanın bir anlamı yok.
  2. Optimizasyonunuz kodu daha az okunabilir hale getirirse, orijinal sürümü en azından bir yorum şeklinde, ancak derleme zamanında ve çalışma zamanında seçilecek alternatif bir sürüm olarak daha iyi tutun. Sorunlarınız ve makineleriniz geliştikçe optimizasyon ihtiyaçlarınız değişebilir ve orijinal kod, bundan beş yıl sonra yapacağınız optimizasyon için daha iyi bir başlangıç ​​noktası olabilir.
  3. Optimize edilmiş sürümünüz minimum düzeyde etkili oluyor ancak kodu daha az okunabilir, daha az evrensel veya daha az kararlı hale getiriyorsa, orijinal sürüme geri dönün. Kazandığınızdan daha fazlasını kaybedersiniz.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.