私は現在、任意のジョブを実行する大規模ループのさまざまな実装をベンチマークしようとしています。ブーストトランスレーションイテレータとboosting countingerを使用すると非常に遅いバージョンが見つかりました。boost transformeriteratorとcounting_iteratorのパフォーマンス上の問題
0とSIZE-1の間のすべての整数の積を任意の整数(私の例ではオーバーフローを避けるために1にすることを選択したもの)で合計する2つのループをベンチマークする小さなコードを設計しました。
彼女は私のコードです:
//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;
}
そして私が手出力:
./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
STDを使用して、私のループの「機能」バージョン::蓄積は、単純なループよりも25倍遅いですバージョン、なぜそう?
は、コード内のコメントをもとに、あなたの助け
コンパイラの最適化を有効にしてコンパイルしましたか? (gccとclangの-O2、MSCVのリリースビルド)そうしないと結果は無意味です。 –
私はgcc(C++ 14)をブースト1.60と "-o2"で試してみました - そして、2番目のバージョンは実行するたびに少し速くなりました....(121msと118ms)... – PiotrNycz