SORU
16 Ocak 2011, Pazar


C memcpy() vs std::copy()

Yoksa std kullanmak daha iyidir, aşağıda gösterildiği gibi işlev, hedef'in kullanmak daha iyi::copy() performans açısından? Neden?

char *bits = NULL;
...

bits = new (std::nothrow) char[((int *) copyMe->bits)[0]];
if (bits == NULL)
{
    cout << "ERROR Not enough memory.\n";
    exit(1);
}

memcpy (bits, copyMe->bits, ((int *) copyMe->bits)[0]);

CEVAP
2 NİSAN 2012, PAZARTESİ


Std genel bilgelik burada karşı çıkacağım::kopyalama, neredeyse fark edilemeyecek küçük bir performans kaybı olacaktır. Ben sadece bir test yaptım ve bu doğru tespit: performans fark ettim. Ancak, kazanan std::copy.

C SHA-2 Uygulama yazdım. Benim testte 5 dizeleri dört SHA-2 sürümleri(224, , 384 256, 512), ve ben döngü 300 kez kullanarak karma. Ben kat Artırmak kullanarak ölçün.zamanlayıcı. 300 döngü sayacı tamamen benim sonuçlar stabilize etmek için yeterli. Test 5'er kez, işlev, hedef'in sürümü ve std arasında değişen koştum::kopya sürüm. Benim kod alır avantaj kapma veri gibi büyük parçaları mümkün olduğunca (birçok diğer uygulamalar ile çalışırchar / char *oysa ben ameliyat ile T / T * (T en büyük yazın kullanıcı uygulaması olan doğru taşma davranış), çok hızlı bellek erişimi en büyük türleri elimden merkezi için performans algoritmamı. Bu sonuçlar şunlardır:

Tamamlanma süresi (saniye olarak) SHA-2 testleri çalıştırın

std::copy   memcpy  % increase
6.11        6.29    2.86%
6.09        6.28    3.03%
6.10        6.29    3.02%
6.08        6.27    3.03%
6.08        6.27    3.03%

Std hızı toplam ortalama artış::memcpy üzerinde kopya: 2.99%

Benim derleyici Fedora 16 x86_64 üzerinde gcc 4.6.3. Benim optimizasyonu bayrak -Ofast -march=native -funsafe-loop-optimizations.

Code for my SHA-2 implementations.

MD5 benim uygulanmasına ilişkin bir test olarak çalıştırmaya karar verdim. Sonuçlar 10 turu yapmaya karar verdim çok daha istikrarlı idi. Ancak, benim ilk birkaç denemeden sonra, çılgınca gelecek bir çalışma farklı sonuçlar aldım, OS aktivite oluyor, çok daha iyi olacaktır diye tahmin ediyorum. Yeniden başlamaya karar verdim.

Aynı derleyici ayarları ve bayrakları. 5 test dizeleri benzer bir set üzerinde 3000 döngü yaptım-2 SHA, daha hızlı. MD5 ve tek bir sürümü var.

Bu son 10 sonuçlarım:

Tamamlanma süresi (saniye cinsinden), MD5 testi çalıştırın

std::copy   memcpy      % difference
5.52        5.56         0.72%
5.56        5.55        -0.18%
5.57        5.53        -0.72%
5.57        5.52        -0.91%
5.56        5.57         0.18%
5.56        5.57         0.18%
5.56        5.53        -0.54%
5.53        5.57         0.72%
5.59        5.57        -0.36%
5.57        5.56        -0.18%

Std hızı toplam ortalama azalma::memcpy üzerinde kopya: 0.11%

Code for my MD5 implementation

Bu sonuçlar, std bazı optimizasyon olduğunu belirtiyorlar::std bu SHA-2 benim testlerde kullanılan kopyala: kopyala:MD5 benim testlerde kullanamadı. SHA-2 testlerinde, her iki dizide std olarak adlandırılan aynı işlevi oluşturuldu::kopyala / memcpy. MD5 benim testlerde, diziler fonksiyonu parametre olarak işleve oldu.

Biraz daha test std yapmak için ne yapabileceğimi görmek için yaptım::daha hızlı yeniden kopyalayın. Cevabı basit olduğu ortaya çıktı: aç bağlantısını zaman optimizasyonu. Bu LTO (- flto gcc option) açık: test sonuçlarım

MD5 testleri tam çalıştırmak için zaman (saniye cinsinden)- flto

std::copy   memcpy      % difference
5.54        5.57         0.54%
5.50        5.53         0.54%
5.54        5.58         0.72%
5.50        5.57         1.26%
5.54        5.58         0.72%
5.54        5.57         0.54%
5.54        5.56         0.36%
5.54        5.58         0.72%
5.51        5.58         1.25%
5.54        5.57         0.54%

Std hızı toplam ortalama artış::memcpy üzerinde kopya: 0.72%

Özetle, std kullanarak bir performans ceza görünmüyor::kopyalayın. Aslında, performans kazanç var gibi görünüyor.

Sonuçların açıklanması

Neden std::copy performans artışı verebilir?

İlk olarak, herhangi bir uygulama için daha yavaş, satır içi uygulaması optimizasyonu açık olduğu sürece olmasını beklemiyorum. Tüm Derleyiciler agresif satır içi; diğer birçok iyileştirmeler sağlar çünkü muhtemelen en önemli optimizasyon. std::copy bağımsız basit copyable bellek sırayla dışarı atılır (ve uygulamaları tüm gerçek dünya şüpheleniyorum) algılayabilir. Bu memcpy yasal olduğunda en kötü durumda,, std::copy hiçbir kötü gerçekleştirmek gerektiği anlamına gelir. memcpy erteler std::copy önemsiz uygulanması derleyici kriterleri karşılaması gerektiğini "her zaman hız veya boyutu için en iyi duruma getirme bu satır".

Ancak std::copy da, bilgilerin daha fazla tutar. std::copy, çağrı işlevi, türleri tutar. memcpy neredeyse tüm yararlı bilgiler atmayan void * üzerinde çalışır. Örneğin, eğer geçersem bir dizi std::uint64_t derleyici veya kütüphane uygulayıcısı olabilir mümkün yararlanmak için 64-bit hizalama ile std::copy, ama olabilir daha zor bunu yapmak için memcpy. Algoritmalar birçok uygulamada, ilk olarak Aralık başında tarafsız bölümünde çalışarak bu iş, o zaman hizalanmış bölümü, sonunda tarafsız bölümü. Eğer uyumlu olmasını garanti ise, o zaman kod işlemci şube tahmini doğru almak için daha kolay ve daha hızlı ve daha kolay olur.

Erken optimizasyon?

std::copy ilginç bir konumda. Hiç memcpy daha yavaş ve herhangi bir modern en iyi duruma getirme derleyici ile bazen daha hızlı olmasını bekliyoruz. Ayrıca, bir şey 30* *29 ** yapabilirsiniz. memcpy std::copy destekler bir yönde (üst üste diğer yön için std::copy_backward ile) üst üste ise tamponunda örtüşme izin vermiyor. memcpy yalnızca işaretçileri herhangi bir kullanımına çalışır çalışır (:: std göster, std::vector, std::deque, ya da kendi özel türü). Diğer bir deyişle, sadece veri parçalarını kopyalamak gerekir std::copy etrafında kullanmalısınız.

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

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Andrea Lewis

    Andrea Lewis

    14 Mart 2013
  • FRED

    FRED

    1 EKİM 2005
  • Strata1000

    Strata1000

    28 EYLÜL 2009