2016-03-20 15 views
0

Şu anda büyük döngüde rastgele iş gerçekleştiren çeşitli uygulamaları karşılaştırmaya çalışıyorum ve boost dönüşüm yineleyicileri ve artırıcı sayma_itleyicileri kullanırken kendimi çok yavaş bir sürümle buldum.Boost transform_iterator ve counting_iterator ile ilgili performans sorunu

0 ve SIZE-1 arasındaki tüm tamsayıların toplamını rasgele bir tam sayı ile toplayan iki döngüyü gösteren küçük bir kod tasarladım (örneğin, taşmayı önlemek için örneğimde 1 olmasını tercih ediyorum).

Onun benim kod:

//STL 
#include <iostream> 
#include <algorithm> 
#include <functional> 
#include <chrono> 

//Boost 
#include <boost/iterator/transform_iterator.hpp> 
#include <boost/iterator/counting_iterator.hpp> 

//Compile using 
// g++ ./main.cpp -o test -std=c++11 

//Launch using 
// ./test 1 

#define NRUN 10 
#define SIZE 128*1024*1024 

struct MultiplyByN 
{ 
    MultiplyByN(size_t N): m_N(N){}; 
    size_t operator()(int i) const { return i*m_N; } 
    const size_t m_N; 
}; 

int main(int argc, char* argv[]) 
{ 
    int N = std::stoi(argv[1]); 
    size_t sum = 0; 
    //Initialize chrono helpers 
    auto start = std::chrono::steady_clock::now(); 
    auto stop = std::chrono::steady_clock::now(); 
    auto diff = stop - start; 
    double msec=std::numeric_limits<double>::max(); //Set min runtime to ridiculously high value 
    MultiplyByN op(N); 


    //Perform multiple run in order to get minimal runtime 
    for(int k = 0; k< NRUN; k++) 
    { 
     sum = 0; 
     start = std::chrono::steady_clock::now(); 
     for(int i=0;i<SIZE;i++) 
     { 
      sum += op(i); 
     } 
     stop = std::chrono::steady_clock::now(); 
     diff = stop - start; 
     //Compute minimum runtime 
     msec = std::min(msec, std::chrono::duration<double, std::milli>(diff).count()); 
    } 
    std::cout << "First version : Sum of values is "<< sum << std::endl; 
    std::cout << "First version : Minimal Runtime was "<< msec << " msec "<< std::endl; 
    msec=std::numeric_limits<double>::max(); //Reset min runtime to ridiculously high value 

    //Perform multiple run in order to get minimal runtime 
    for(int k = 0; k< NRUN; k++) 
    { 
     start = std::chrono::steady_clock::now(); 

     //Functional way to express the summation 
     sum = std::accumulate( boost::make_transform_iterator(boost::make_counting_iterator(0), op), 
         boost::make_transform_iterator(boost::make_counting_iterator(SIZE), op), 
         (size_t)0, std::plus<size_t>()); 

     stop = std::chrono::steady_clock::now(); 
     diff = stop - start; 
     //Compute minimum runtime 
     msec = std::min(msec, std::chrono::duration<double, std::milli>(diff).count()); 
    } 
    std::cout << "Second version : Sum of values is "<< sum << std::endl; 
    std::cout << "Second version version : Minimal Runtime was "<< msec << " msec "<< std::endl; 
    return EXIT_SUCCESS; 
} 

Ve çıkış alıyorum:

std :: birikir kullanan benim döngünün "işlevsel" sürüm basit döngü 25'den kat daha yavaştır
./test 1 
First version : Sum of values is 9007199187632128 
First version : Minimal Runtime was 433.142 msec 
Second version : Sum of values is 9007199187632128 
Second version version : Minimal Runtime was 10910.7 msec 

sürüm, neden böyle? Optimizasyon seviyesini belirtmedi yana

Yardımlarınız için şimdiden teşekkür ederim

kodunda Yorumlarınız dayanarak
+0

Derleyici optimizasyonları etkinleştirildiniz mi? (Gcc ve clang için -O2, MSCV için sürüm oluşturma) Aksi halde sonuç anlamsızdır. –

+2

Gcc (C++ 14) ile boost 1.60 ve "-o2" denemeyi denedim - ve ikinci versiyon her çalıştırdığımda biraz daha hızlı .... (121ms ve 118ms) ... – PiotrNycz

cevap

1

, sen

g++ ./main.cpp -o test -std=c++11 

ile bu derledik, g ++ varsayılan kullanılan -O0 olan ayar, yani optimizasyon yok.

Bu, derleyicinin hiçbir şey yazmamış olduğu anlamına gelir. Standart kitaplık veya destek gibi şablon kitaplıkları, performans için satır içi bağlıdır. Ek olarak, derleyici çok fazla ekstra kod üretecek, bu da optimal olmaktan çok uzaktır - bu ikili dosyalarda performans karşılaştırması yapmak hiç mantıklı değildir.

Optimizasyon etkinleştirilmiş olarak yeniden derleyin ve anlamlı sonuçlar elde etmek için testinizi tekrar deneyin.

+0

Performanslar gerçekten çok -O3 bayrağı ile daha iyi, bu bayrak kullanarak her iki yöntem için yaklaşık 100ms var. teşekkür ederim – Tobbey

İlgili konular