ネタ元 → マルチ スレッドで FizzBuzz
いやまったく。くだらん遊びにワザをちらつかせるのが職人の粋ってもんだ。
で、ネタ元とおんなじことをIntel TBBでやってみた。
スレッド数はTBBにおまかせ。よきにはからえーみたいな。
/*
cl -EHsc -MD -I<TBB_INC_DIR> fizzbuzz_parallel_for.cpp -link -libpath:<TBB_LIB_DIR>
*/
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
#include <utility>
#include <tbb/tbb.h> // tbb::*
int main() {
const int N = 200000;
// 前準備
std::vector<std::pair<int,std::string>> result;
for ( int i = 1; i <= N; ++i ) {
result.push_back(std::pair<int,std::string>(i,""));
}
// FizzBuzz本体
auto fizzbuzz = [&](const tbb::blocked_range<int>& range) {
for ( int n = range.begin(); n != range.end(); ++n ) {
bool div3 = (n % 3 == 0);
bool div5 = (n % 5 == 0);
if ( div3 && div5 ) { result[n-1].second = "FizzBuzz"; }
else if ( div3 ) { result[n-1].second = "Fizz"; }
else if ( div5 ) { result[n-1].second = "Buzz"; }
}
};
// 範囲 [1,N+1)
tbb::blocked_range<int> range(1,N+1);
tbb::tick_count t0, t1;
// シングルスレッドでは...
t0 = tbb::tick_count::now();
fizzbuzz(range);
t1 = tbb::tick_count::now();
std::cout << "single: " << (t1 - t0).seconds() << std::endl;
// parallel_forで並列化
t0 = tbb::tick_count::now();
tbb::parallel_for(range, fizzbuzz);
t1 = tbb::tick_count::now();
std::cout << "parallel: " << (t1 - t0).seconds() << std::endl;
/*
std::for_each(result.begin(), result.end(),
[](const std::pair<int,std::string>& item) {
if ( item.second.empty() ) std::cout << item.first << std::endl;
else std::cout << item.second << std::endl;});
*/
}
実行結果:
single: 0.0236158
parallel: 0.0148314
およそ1.6倍…dual-coreならそんなもんでしょね。