Nerede optimizasyon yapıyorsunuz?


9

Hız için optimize etmek için iki alan vardır:

  • En çok zamanın nerede geçtiği
  • En çok adlandırılan kod

Optimizasyona başlamak için en iyi yer hangisidir?

Genellikle en çok çağrılan kodun yürütme süreleri düşüktür. Daha yavaş, daha az çağrılan alanları optimize ediyor veya daha hızlı, daha yoğun kullanılan alanları optimize etmek için zaman harcıyor musunuz?


Uygulamalarınızın, müşterilerinizin veya sunucularınızın en yüksek düzeyde şikayetçi olup olmadığına bağlı olarak, müşterilerinizi veya mimarinizi en çok vurgulayan alanını optimize edin.
Andy

Bu bir değer denklemi - cevap da olabilir. Gerçek bir analiziniz olmadığında, en iyi fikirlerinizin büyük olasılıkla getirisine dayanarak bağırsağınızla devam edersiniz.
Nicole

Ne. Yığın üzerinde zamanın büyük bir kısmında kod arayın.
Mike Dunlavey

Yanıtlar:


4

Zamanın% 95'indeki küçük verimlilikleri görmezden gelmelisiniz. Önce doğru şekilde çalışmasını sağlayın , ardından analiz edin ...

Senin tasarımın.

Yüksek seviyeli algoritmalar seçiminizin, yazılımınızın genel performansı üzerinde büyük bir etkisi olabilir; bu, önemsiz görünen bir seçimin, programın başlaması için 20 dakika beklemek ile hızlı, duyarlı bir kullanıcı arayüzüne sahip olmak arasındaki fark anlamına gelebilir.

Örneğin, bir 3D oyunda: sahne grafiğiniz için basit bir nesne listesi ile başlarsanız, nispeten az sayıda nesne için son derece düşük performans görürsünüz; ancak bunun yerine çizim sırasında bir hacim hiyerarşisi (bir oktree veya BVH gibi) ve ağacın kesik kısımlarını uygularsanız, büyük bir performans artışı görürsünüz.

Tasarımınız doğru göründüğünde, ...

Düşük seviye mantık.

Alt seviye algoritmaların da önemli bir etkisi olabilir. Görüntü işleme yaparken, örneğin görüntüyü yanlış sırada okursanız, sabit L2 önbellek özledikleri ile karşılaştıkça büyük yavaşlamalar yaşarsınız; işlemlerinizi yeniden düzenlemek, performansta on kat artış anlamına gelebilir.

Bu noktada, program zamanının çoğunun harcandığı yeri bulun ve ortadan kaldırın.


Üzerinde çalıştığım program doğru. 30 saniyeden daha uzun bir süre alabilen bir web hizmeti olduğu için yapabiliyorsak daha hızlı hale getirmek istiyoruz.
Michael K

1
@Michael: Bu durumda, bazı tipik program yürütmelerini analiz etmek ve kodun en yavaş çalışan bölümlerini belirlemek için bazı profil oluşturma aracı alma zamanı gelmiştir. Bunun için bir araç kullanmanızı tavsiye ederim. Sezgiye göre belirli bir miktar yapabilirsiniz, ancak bazen bir çağrı olan bir API'nin kendi kodunuz yerine önemli miktarda zaman aldığı bir sürpriz bulacaksınız. Bu durumda, API'ye bakma ve başka hangi işlevlerin mevcut olduğunu görme zamanı veya kendi değiştirme işlevinizi yazmanız gerekiyor ... Gerçek performans domuzu her zaman şüpheli performans domuzu değildir ...
FrustratedWithFormsDesigner

1
Bir profil oluşturma aracımız var. Hala öğreniyorum ve bilgiyle ne yapacağım. Bu benim için nispeten yeni bir konu ve çok ilginç.
Michael K

@Michael: Güzel! (Umarım) başarılı performans ayarlama yolundasınız! :)
FrustratedWithFormsDesigner

+1: Bunu söyleyecektim, ama çok daha etkili.
Dominique McDonnell

3

İlk olarak, kodunuzun zamanını nerede harcadığını öğrenmek için bir profil oluşturucu çalıştırın.

Ardından, hangilerinin optimizasyonunun kolay göründüğünü görmek için bu yerlere bakın.

Önce en büyük kazancı elde edecek en kolay düzeltmeleri arayın (düşük asılı meyveyi tercih edin). Tam olarak ne kadar önemli olduğu konusunda fazla endişelenmeyin. Kolaysa, düzeltin. Toplayacak. 25 kolay düzeltme, 1 büyük düzeltmeden daha hızlı olabilir ve kümülatif etkileri daha büyük olabilir. Zorsa, daha sonra öncelik verebilmek için bir not alın veya bir hata raporu gönderin. Bu noktada "büyük" veya "küçük" hakkında çok fazla endişelenmeyin - çok az zaman harcayan işlevlere ulaşıncaya kadar yapın. Bunu yaptıktan sonra, ortaya çıkardığınız diğer sorunlardan hangisinin en az zaman yatırımı için en büyük kazancı elde edebileceği konusunda daha iyi bir fikre sahip olmalısınız.

Performans değişikliklerinizin umduğunuz etkileri olduğunu doğrulamak için bir tür regresyon testi olarak düzeltmelerinizden sonra profil oluşturmayı takip etmeyi unutmayın. Ayrıca, hiçbir işlevin bozulmadığından emin olmak için regresyon paketinizi çalıştırmayı unutmayın. Bazen kötü performans çözümlere işaret eder ve performansı düzeltmeye çalışmak işlevselliği bozar.

Optimize edilemeyen ancak çok fazla zaman harcayan küçük işlevler, nerelerde optimizasyon yapılacağına dair ipuçları olabilir. Bu işleve neden bu kadar çok deniyor? Bu kadar küçük bir işlevi çağıran bir işlevi var mı? İş kopyalanıyor mu, yoksa gereksiz iş mi yapılıyor? Sık sık çağrılmasından emin olana kadar yığının çağrıldığı sürelere bakın ve verimsiz bir algoritmaya sahip daha büyük bir işlev bulup bulamayacağınıza bakın.

Eklemek için düzenlendi: Uzun süren belirli bir işlevselliğe sahip olduğunuzdan, yukarıdaki adımları yalnızca belirli bir işlev 10 veya daha fazla kez çalıştırılarak yapmayı deneyin.


2

Söylemesi zor. Bu gerçekten bu kodun ne yaptığına bağlıdır. Bir performans testi yapın, bir performans profili edinin ve çeşitli alanlarda ne kadar gerçek zaman harcandığına bakın ve görün . Genellemeleriniz ... genellemelerdir ve projeden projeye değişir.

Örneğin, en çok çağrılan kod bir dosyaya veya konsola oturum açabilir. Daha basit hale getirilemeyen bir veya iki kod satırı varsa ve bunun gibi bir şeyi optimize etmek için herhangi bir çaba aslında kodlamanın maliyetine değmeyebilir. En az olarak adlandırılan kod, bazı korkunç karmaşık işlevlerde kullanılan canavar boyutlu bir sorgu olabilir. İşlevi yalnızca bütün bir yürütme çalışması (basit günlük deyimi için vs 10000) üzerinden 100 kez denilen olsun olabilir, ama her çağrı kez 20 saniye sürer eğer belki ishal en o nereye optimizasyon başlamalıdır? Ya da başka bir yol olabilir, büyük sorgu en çok adlandırılan ve günlük deyimi her 100 sorgu için yalnızca bir tane çağırdı ...

Genellikle ne olacağı hakkında bir fikrim yoksa, bu tür bir şey hakkında endişelenmiyorum (performans ayarlaması yapana kadar).


1

Peki "biz" genellikle bir şey kabul edilemez derecede yavaş olduğunda belirgin bir optimizasyon ihtiyacı olana kadar optimizasyon yapmayız.

Ve bu ihtiyaç kendini gösterdiğinde, genellikle optimizasyon için tam olarak neyin gerekli olduğu konusunda iyi ipuçları taşır.

Bu yüzden cevap olağan: "Değişir."


1

Bir profil oluşturucuyu bir avuç tipik çalıştırmada kullanmalı ve oraya ne kadar veya ne sıklıkta sahip olursanız olun, kodun her bir bölümünde toplam zaman harcamasına bakmalısınız . Bu parçaları optimize etmek her zaman bir hız artışı sağlamalıdır.

Uygulama dilinizin ne kadar düşük seviyede olduğuna bağlı olarak, hangi bölümlerin çoğu önbellek kaybına neden olduğunu öğrenmelisiniz. Arama kodunun birleştirilmesi burada yardımcı olacaktır.


1

Sorun "en fazla zamanın nerede geçtiği" ifadesinin belirsiz olmasıdır.

"Program sayacının en sık bulunduğu yer" anlamına geliyorsa, o zaman string-Compare, memory-tahsisi, math library işlevlerinde en çok zaman harcanan programları gördüm. Başka bir deyişle, günlük programcının asla dokunmaması gereken işlevler.

"Programcının kodunda, zamanın büyük bir kısmını tüketen ifadeler nerede çalıştırılırsa" bu daha kullanışlı bir kavramdır.

"En çok adlandırılan kod" kavramıyla ilgili sorun, bunun ne kadar sürdüğü, ne sıklıkta çağrıldığının ve arama başına ne kadar sürenin (callees ve G / Ç dahil) çarpımıdır. Geçen süre birkaç büyüklük sırasına göre değişebileceğinden, çağrılma sayısı size sorunun ne kadar olduğunu söylemez. A fonksiyonu 10 kez çağrılabilir ve 0.1 saniye sürebilir, B fonksiyonu 1000 kez çağrılabilir ve mikrosaniye alabilir.

Bir şey olacak bakmak gerektiğini söyleyecektir şudur: bir kod satırı zaman harcanması neden olan her o yığının üzerinde . Örneğin, bir kod satırı etkin nokta ise veya bir kütüphane işlevine çağrı ise veya 30 seviyeli bir çağrı ağacında 20. çağrı ise,% 20 zamandan sorumluysa , o zaman zamanın% 20'sinde yığını üzerinde. Yığının rastgele zaman örneklerinin her birinin% 20 şans gösterme şansı olacaktır. Dahası, G / Ç sırasında numuneler alınabiliyorsa, G / Ç için hangi hesapların boşa harcandığını göstereceklerdir, bu da boşa harcanan CPU döngüleri kadar veya daha fazla israfa neden olabilir.

Ve bu kaç kez çağrıldığından tamamen bağımsızdır.


'Günlük programcı asla dokunmamalı' demekle, dokunma ihtimaliniz yok mu? Ayrıca, yığının örneklenmesi pratik bir profil oluşturma yöntemi midir?
Michael K

@Michael: Evet, yığını örneklemek, Zoom gibi modern profillerin dayandığı bir yöntemdir . Ayrıca, tamamen manuel şaşırtıcı derecede iyi çalışıyor .
Mike Dunlavey

Çok ilginç. Şimdi yapacak biraz dersim var!
Michael K

@Michael: Yasal ortak sorumluluk kavramı gibi. Bir noktada, bilgisayarın bir talimatta olması sorumluluğu sadece bu talimatın değil, aynı zamanda üstündeki her çağrının yığındaki ortak sorumluluğudur. Bunlardan herhangi birinin ortadan kaldırılması, söz konusu duruma girmesini engelleyecektir.
Mike Dunlavey

0

Belirli bir neden olmadığı sürece en fazla zamanın nerede harcandığını optimize edin (yani çoğu zaman, insanların 5 dakika veya 10 dakika içinde bitip bitmeyeceklerini gerçekten umursamayacakları zaman uyumsuz işleme tabi tutuluyor). Doğal olarak en çok adlandırılan kod, toplam geçen sürenin nispeten büyük bir bölümünü rafa çekme eğiliminde olacaktır, çünkü binlerce kez yaptığınızda kısa yürütme süreleri bile toplanır.


0

En çok zaman alan kod üzerinde çalışmanız gerekir. Çalışma süresinin yalnızca yüzde birkaçını oluşturan kodu geliştirmek size yalnızca küçük bir gelişme sağlayabilir.

Hangi kodun en fazla zaman aldığını öğrenmek için ölçüm yaptınız mı?


0

Bir süper bilgisayar satıcısı için kıyaslama ve pazarlama yapardım, bu yüzden rekabeti hızlı bir şekilde yenmek en önemli şey değildi, SADECE şeydi. Bu tür bir sonuç, iyi algorthm ve en yoğun CPU yoğun bölümlerinin verimli bir şekilde zirveye ulaşmasına izin verecek bir veri yapısının bir kombinasyonunu kullanmanızı gerektiriyordu. Bu, en yoğun işlemlerin ne olacağı ve ne tür veri yapılarının en hızlı çalışmasına izin vereceği konusunda oldukça iyi bir fikre sahip olmanız gerektiği anlamına geliyordu. Daha sonra, uygulamayı bu optimize edilmiş çekirdeklerin / veri yapılarının etrafına inşa etmek meselesiydi.

Daha genel anlamda, gerçek ayardan sonra tipik. Profiliniz, sıcak noktalara bakın ve hızlandırabileceğinizi düşündüğünüz sıcak noktalar üzerinde çalıştığınız yerlerdir. Ancak bu yaklaşım nadiren size mümkün olan en hızlı uygulamaya yakın bir şey sağlayacaktır.

Daha genel olarak, (algoritmik hatalar dayanmaz), modern makineler için performansın üç şey tarafından belirlendiğini düşünmelisiniz: veri erişimi, veri erişimi ve veri erişimi! Bellek hiyerarşisi hakkında bilgi edinin (kayıtlar, önbellekler, TLB'ler, sayfalar vb.) Ve veri yapılarınızı mümkün olduğunca iyi kullanmak için tasarlayın. Genellikle bu, döngülerin kompakt bir bellek alanı içinde çalışmasını istediğiniz anlamına gelir. Bunun yerine sadece bir uygulama yazarsanız (veya verilirse) ve en iyi duruma getirmeye çalışırsanız, genellikle bellek hiyerarşisini zayıf kullanan veri yapıları ile sararsınız ve veri yapılarını değiştirmek genellikle büyük bir yeniden düzenleme alıştırması içerir. sık sık sıkışmış.


0

Optimizasyon çabanızın geri dönüşünü istiyorsanız, en çok zaman alan koda bakmanız gerekir. Genel hedefim, zamanın en az% 80'ini alan bir şey. Genelde 10 kat performans artışı hedefliyorum. Bu bazen bu kodun tasarımında büyük bir değişiklik gerektirir. Bu tür bir değişiklik size yaklaşık dört kat daha hızlı çalışan bir şey sağlar.

Tüm zamanların en iyi performans kazancım, çalışma süresini 3 günden 9 dakikaya düşürmektir. Optimize ettiğim kod 3 günden 3 dakikaya kadar gitti. Uygulamanın yerini alan uygulama, bunu 9 saniyeye düşürdü, ancak bu dilde bir değişiklik ve tam bir yeniden yazma gerektiriyordu.

Zaten hızlı bir uygulamayı optimize etmek aptalca bir iş olabilir. Yine de en çok zaman alan bölgeyi hedeflerdim. Anında geri dönmek için zamanın% 10'unu kullanarak bir şey alabiliyorsanız, yine de zamanın% 90'ına ihtiyacınız vardır. Hızla azalan getiri kuralına ulaştınız.

Kural için neyi optimize ettiğinize bağlı olarak hala geçerlidir. Büyük kaynak kullanıcılarını arayın ve optimize edin. Optimize ettiğiniz kaynak sistem darboğuysa, yaptığınız tek şeyin darboğazı başka bir kaynağa dönüştürmek olduğunu görebilirsiniz.


0

Tipik olarak, çoğu durumda bir döngüde milyarlarca kez çağrılan işlevler değil, çoğu durumda daha az fonksiyon olacaktır.

Örnek tabanlı profil oluşturma (bir araçla veya elle) yaptığınızda, genellikle en büyük sıcak noktalar, iki tamsayıyı karşılaştırma işlevi gibi basit şeyler yapan küçük yapraklı aramalarda olur.

Bu işlev çoğu zaman, eğer varsa, çok fazla optimizasyondan faydalanmayacaktır. En azından bu granüler sıcak noktalar nadiren birinci önceliğe sahiptir. Sorun yapıcı olabilecek yaprak işlevini çağıran işlev veya bir alt optimal sıralama algoritması gibi, işlevi çağıran işlevi çağırır. İyi araçlarla callee'den caller'a inebilir ve callee'yi aramak için en çok kimin zaman harcadığını görebilirsiniz.

Mikro düzeyde çok verimsiz bir şey yapmadıkça genellikle callees takıntısı ve arama profili aşağı arayanlara bakmak bir hata. Aksi takdirde, küçük şeyleri aşırı derecede terliyor ve büyük resmi gözden kaçırıyor olabilirsiniz. Sadece bir profil oluşturucu, sizi önemsiz şeylere takıntıdan korumaz. Doğru yönde sadece ilk adım.

Ayrıca, kullanıcıların gerçekte yapmak istedikleri şeylerle uyumlu işlemleri belirlediğinizden emin olmalısınız, aksi takdirde müşterilerin ürünle yaptıklarıyla hizalanmadığı için ölçümlerinizde ve kıyaslamalarınızda tamamen disiplinli ve bilimsel olmak değersizdir. Bir keresinde, bir küpü bir milyar yüze ayırmak için bir alt bölüm algoritmasından cehennemi ayarlayan bir meslektaşım vardı ve bununla gurur duyuyordu .... hariç, kullanıcılar basit 6 çokgen küpleri bir milyara bölmedi yönleri. Her şey, alt bölümlere ayırmak için 100.000'den fazla çokgen içeren bir üretim araba modelinde çalışmaya çalıştığında taramayı yavaşlattı, bu noktada bir taramayı yavaşlatmadan 2 veya 3 alt bölümleme bile yapamadı. Basitçe söylemek gerekirse, gerçekçi olmayan küçük giriş boyutları için süper optimize edilmiş kod yazdı '

Kodun sürdürülebilirliğini en azından bir şekilde bozma eğiliminde olan tüm bu optimizasyonların çok az kullanıcı yararı ve sadece kod tabanı için tüm negatifleri olduğu için, kullanıcılarınızın ilgi alanlarına uygun gerçek kullanım durumlarını optimize etmelisiniz, aksi takdirde değersizdir.

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.