Alttaki sebebi görmek için jitter'in oluşturduğu makine koduna bakmanız gerekir. Araçlar> Seçenekler> Hata ayıklama> Genel> JIT optimizasyonunu kaldır seçeneğinin işaretini kaldırın. Sürüm oluşturmaya geçin. Birinci ve ikinci döngülerdeki bir kesme noktası ayarlayın. Ne zaman hata ayıklama> Windows> Disassembly.
Sen döngü organları için makine kodunu görürsünüz:
sum1 += i;
00000035 add esi,eax
Ve:
sum2 += i;
000000d9 add dword ptr [ebp-24h],eax
Veya başka bir deyişle
,
sum1
değişken CPU kayıt
esi
saklanır. Ancak
sum2
değişken, bellekte, yöntemin yığın çerçevesinde saklanır. Büyük, büyük fark. Kayıtlar çok hızlı, hafıza yavaş. Yığın çerçevesi için bellek, L1 önbelleğinde, bu önbelleğe erişen 3 makinenin gecikme süresine sahip olacak. Mağaza tamponu, çok sayıda yazma ile hızlıca boğulur ve bu da işlemcinin durmasına neden olur.
Değişkenleri CPU kayıt defterinde tutmanın bir yolu bulmak one of the primary jitter optimization duties. Ama bunun sınırlamaları var, özellikle x86'nın az sayıda kaydı var. Hepsi tamamlandığında, jitter seçeneğinin bir seçeneği yoktur, ancak bunun yerine belleği kullanır. using
ifadesinin başlık altında ek bir gizli yerel değişkene sahip olduğunu unutmayın, bu nedenle bir etkisi vardır.
İdeal olarak, jitter optimize edici, yazmaçların nasıl ayrılacağı konusunda daha iyi bir seçim yapmış olur. Döngü değişkenleri (bunu yaptı) ve toplam değişkenler için bunları kullanma. Önde gelen bir derleyici, kod analizini gerçekleştirmek için yeterli zamana sahip olur. Ancak tam zamanında bir derleyici sıkı zaman kısıtlamaları altında çalışır.
Temel karşı önlemler şunlardır:
ayrı yöntemlerle içine kodunu böylece ESI gibi bir kayıt yeniden kullanılabilir ayrıl
- .
- Titreşmeyi zorla kaldırma (Proje> Özellikler> Yapılandırma sekmesi> "32 bit tercih et" seç). x64 8 ek kayıt sağlar.
son kurşun eski x64 titreme (kullanmak .NET 3.5 hedef) için geçerlidir, ama ilk 4,6 kullanılabilir hale x64 seğirme yeniden yazma (aka RYuJIT) için. Eski bir jitter, kodu optimize etmek için çok zaman harcadığı için gerekli olan bir yeniden yazma. Hayal kırıklığı yaratan RyuJIT, hayal kırıklığı yaratan bir şöhrete sahip. Sanırım optimize edicisi burada daha iyi bir iş çıkartabilir.
Belki de 'Console.WriteLine' yerine değişkenlerle deneyin?Bu sorun olabilir. – ispiro
Kodunuzu linqpad'de çalıştırdığımda, her iki kod bloğu için de ~ 2.5 saniye verir. Ideone üzerinde çalışırken her iki blok için de ~ 0,3 saniye verir: https://ideone.com/ReOpaH. – Chris
Ayrıca uygun bir kronometre kullanın. Tarih saatini, kronometreyi kullanmak istediğinizi belirtiyorsunuz ama o zaman bir tane kullanmıyorsunuz. – Chris