SORU
29 NİSAN 2012, Pazar


Neden yerel değişkenler olun ekleme yapar .NET kod daha yavaş

Neden döngü için bu ilk iki satırı yorum ve B oranında bir hızlanma üçüncü sonuç uncommenting mu?

int count = 0;
for (uint i = 0; i < 1000000000;   i) {
    var isMultipleOf16 = i % 16 == 0;
    count  = isMultipleOf16 ? 1 : 0;
    //count  = i % 16 == 0 ? 1 : 0;
}

Zamanlaması oldukça farklı bir derleme kod arkasında: döngü içinde 13 vs 7 talimatları. Platform Windows 7 çalışıyor .NET 4.0 x 64. Kodu en iyi duruma getirme etkin ve test uygulamayı VS2010 dışında çalıştırıldı. [Güncelleme:Repro project, doğrulama için yararlı ayarları proje.]

Ara boolean ortadan kaldırır temel bir optimizasyon, 1980 Dragon Book çağda benim basit biri. Nasıl optimizasyon ÇİL üretme veya 64 makine kodu JİTing uygulandığında aldın değil mi?

Bir "Gerçekten derleyici bu kodu optimize etmek istiyorum," geçiş? lütfen var Erken optimizasyonu love of money benzer olduğunu bu duyguyu çok iyi anlıyorum ederken bu gibi sorunları kendi rutinleri dağılmış olduğunu karmaşık bir algoritma profil için çalışırken hayal kırıklığını görebiliyordum. Normalde derleyici hafife almak ne noktaları ile çalışmak istiyorum ama büyük ölçüde el verdiği tarafından geliştirilmiş olabilir, daha geniş bir sıcak bölge hiçbir ipucu var. Eminim burda bir şeyler kaçırıyorum umarım.

Güncelleme:Hız farklılıkları da 86, ama yöntem tam zamanında derlenen sıralamasına bağlı oluşur. Why does JIT order affect performance? bkz

Assembly koduistediği gibi ():

    var isMultipleOf16 = i % 16 == 0;
00000037  mov         eax,edx 
00000039  and         eax,0Fh 
0000003c  xor         ecx,ecx 
0000003e  test        eax,eax 
00000040  sete        cl 
    count  = isMultipleOf16 ? 1 : 0;
00000043  movzx       eax,cl 
00000046  test        eax,eax 
00000048  jne         0000000000000050 
0000004a  xor         eax,eax 
0000004c  jmp         0000000000000055 
0000004e  xchg        ax,ax 
00000050  mov         eax,1 
00000055  lea         r8d,[rbx rax] 
    count  = i % 16 == 0 ? 1 : 0;
00000037  mov         eax,ecx 
00000039  and         eax,0Fh 
0000003c  je          0000000000000042 
0000003e  xor         eax,eax 
00000040  jmp         0000000000000047 
00000042  mov         eax,1 
00000047  lea         edx,[rbx rax] 

CEVAP
30 NİSAN 2012, PAZARTESİ


Soru "Neden benim makinede böyle bir fark görüyor muyum?". Böyle büyük bir hız farkı yeniden ve şüpheli bir şey ortamınıza yok edemem. Çok zor olsa neler olabileceğini anlatmak için. Bir süre önce ayarladığınız (derleyici) bazı seçenekler olabilir ve onlar hakkında unuttum.

Bir konsol uygulaması oluşturun, Yayın modu (86) yeniden ve VS dışında çalıştırmak. Sonuçlar her iki yöntemde de hemen hemen aynı, 1.77 saniye. Burada tam kod:

static void Main(string[] args)
{
    Stopwatch sw = new Stopwatch();
    sw.Start();
    int count = 0;

    for (uint i = 0; i < 1000000000;   i)
    {
        // 1st method
        var isMultipleOf16 = i % 16 == 0;
        count  = isMultipleOf16 ? 1 : 0;

        // 2nd method
        //count  = i % 16 == 0 ? 1 : 0;
    }

    sw.Stop();
    Console.WriteLine(string.Format("Ellapsed {0}, count {1}", sw.Elapsed, count));
    Console.ReadKey();
}

Lütfen, 5 dakika olan herkes kodu kopyalayın, yeniden, VS dışında çalışan ve bu cevap için yorum sonrası sonuçlar. Deyip kaçmak istiyorum "benim makine üzerinde çalışıyor".

EDİT

Bir yarattık emin olmak için64 bitVe sonuç olarak benzer soru win uygulamailk yöntem daha yavaştır(1.57 sn) ikincisi (1.05 sn). Gözlemlerime göre fark 3'ü hala bir çok şey var. Bir hata var gibi gözüküyor .NET4 64 bit JİT derleyici.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Friday NightFort

    Friday Night

    15 EYLÜL 2011
  • Matt Davis

    Matt Davis

    4 ŞUBAT 2006
  • NewsyTech

    NewsyTech

    2 AĞUSTOS 2010