SORU
9 ŞUBAT 2014, Pazar


C 64-bit döngü performansı x 86

İhtiyacım olan bir İnternet Sağlama işlevi (bir tamamlayıcı sağlama toplamı) için bazı IPv4 ICMP işleme kodu kullanarak ham yuva kadar tökezledi davranışı açıklayamayacağım bir 64-bit Intel işlemci (kullanarak gcc 4.8.2). Eğer herkes bu biraz ışık tutacak diye merak ediyordum.

İlk sağlama fonksiyonu 32-bit bir akü kullanarak ve 16-bit meblağlar sahne uygulanmaktadır. Sonra aynı 64-bit akümülatör ve 32-bit bir miktarda kullanarak, daha az miktarda daha hızlı yürütülmesine neden olacağını düşünüyorum uygulanmaktadır. Sonuç ilk uygulama iki kat daha hızlı ikinci olarak (O3 optimizasyonu ile) çalışır. Ben sadece nedenini çözemiyorum...

Aşağıdaki kod aslında doğru sağlama toplamı (basitleştirdim) yapmaz ama sorunu göstermektedir. Hem 64-bit 64-bit Windows platformu üzerinde çalışan olarak (LP64: 16-bit tamsayı 32-bit, uzun 64-bit işaretçileri 64-bit) kısa derlenmiş.

  1. 32-bit akümülatör ve 16-bit toplar

    unsigned short
    cksum_16_le(unsigned char* data, size_t size)
    {
        unsigned short word;
        unsigned int sum = 0;
        unsigned int i;
    
        for(i = 0; i < size - 1; i  = 2)
            sum  = *((unsigned short*) (data   i));
    
        sum = (sum & 0xffff)   (sum >> 16);
        sum = (sum & 0xffff)   (sum >> 16);
    
        return ~sum;
    }
    

Aynı 10k veriler üzerinde 50.000 işlev çağrıları: ~1.1 saniye.

  1. 64-bit akümülatör ve 32-bit toplar

    unsigned short
    cksum_32_le(unsigned char* data, size_t size)
    {
        unsigned long word;
        unsigned long sum = 0;
        unsigned int i;
    
        for(i = 0; i < size - 3; i  = 4)
            sum  = *((unsigned int*) (data   i));
    
        sum = (sum & 0xffffffff)   (sum >> 32);
        sum = (sum & 0xffffffff)   (sum >> 32);
        sum = (sum & 0xffff)   (sum >> 16);
        sum = (sum & 0xffff)   (sum >> 16);
    
        return ~sum;
    }
    

Aynı 10k veriler üzerinde 50.000 işlev çağrıları: ~2.2 saniye.

Güncelleme:

Donanım sorunu nedeniyle olduğunu görünüyor. Çalışan bellek diags arada bir otobüs eşlik hataları (bu 32-bit sürümü en fazla 16-bit sürümünü etkileyecek ama yapacak bir şey yok neden emin değilim) saptandı. Kodu diğer sunucularda beklendiği gibi çalışır. Sonraki birkaç saat içinde silin (donanım ile ilgili olarak, özellikle yararlı değil artık).

Son güncelleme:

İlginçtir, değiştirme for döngüler while döngüler ve derleme ile O3 optimizasyonu (aşağıda gösterilen için 64-bit akümülatör kutu) alır hem 32-bit ve 64-bit akümülatör durumlar için çalışma sırasında aynı hız. Bu derleyici döngü çözümü (işin garibi, for döngü göz önüne sermek değil) gerçekleştirir ve toplamak mmx kayıtları kullanarak gerçekleştirir

uint64_t sum = 0;
const uint32_t* dptr = (const uint32_t*) data;

while (size > 3)
{
    sum  = (uint32_t) *dptr  ;
    size -= 4;
}

CEVAP
25 EYLÜL 2014, PERŞEMBE


Böyle benzer bir konu daha önce vardı; bizim kod ya da herhangi bir sorun bulamadım. AMA benim için çalıştı ne derleyici değişiyordu.

Benim tahminim GCC itiraz Meclisi yazılı.

Eğer uygulamanızın derleme olabilir eğer bu konuda daha fazla ışık tutabiliriz ama sadece buraya gitmek için yeterli bilgi yok.

Ne buldum benim kodun derlenmiş halini açtım zaman bütün bir yöntemi birkaç kez yeniden yazma olduğunu. ama bu sadece benim için olabilir.

Bu sana yardımcı umuyoruz, bu konuda daha fazla bilgi için küçük bir yerde yok.

Eğer Öğrenci kabul edeceğini tahmin etmem gerekirse, decompiled kodu döngü için işaret olacağını oldukça eminim. Bu konu ile çok ilgileniyorum geri dönüş yorum lütfen.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • infodirt

    infodirt

    11 Mart 2009
  • Kat Krazy

    Kat Krazy

    12 Kasım 2010
  • sk8ingis4me

    sk8ingis4me

    16 Mart 2006