Intel Concurrent Collections (CnC) ってシロモノを見つけました。
並列化のためのライブラリなんだけど、フツーのたとえば pthread だとか PPL, TBB とは一味違ってます。
CnC が提供する構成要素は大きく3つ:
- step : 処理単位
- item : stepの入力/出力
- tag : stepの着火装置
「tagによって着火されたstepはitemから読み、処理を行い、itemに結果を書く」
が基本構成。
これ使って複利計算をやってみます。
n番itemは"n年目の残高"を表すこととし、n番stepでのおしごとを
「n-1番item を読出し 1+利率を掛けて n番item に書く」とします。
そうすればこいつをN個数珠つなぎにして一気に着火すればN年目までの残高が求まるよね。
#include <iostream>
#include <iomanip>
#include <array>
#include <cnc/cnc.h>
using namespace std;
struct my_context;
struct my_step {
int execute(const int& n, my_context& ctx) const;
};
struct my_context : public CnC::context<my_context> {
CnC::step_collection<my_step> steps;
CnC::tag_collection<int> tags;
CnC::item_collection<int,double> items;
double rate;
my_context() : steps(*this), tags(*this), items(*this) {
tags.prescribes(steps, *this);
steps.consumes(items);
steps.produces(items);
}
};
int my_step::execute(const int& n, my_context& ctx) const {
double result;
ctx.items.get(n-1, result);
result *= (1.0 + ctx.rate);
ctx.items.put(n, result);
return CnC::CNC_Success;
}
int main() {
my_context ctx;
ctx.rate = 0.05;
ctx.items.put(0, 10000.0);
const int duration = 10;
for ( int n = 1; n <= duration; ++n ) {
ctx.tags.put(n);
}
ctx.wait();
array<double, duration+1> balances;
for ( const auto& item : ctx.items ) {
balances[item.first] = *item.second;
}
for ( const auto balance : balances ) {
cout << balance << endl;
}
}
これでできちゃうです。スレッドだのタスクだの考えなくていい。
そーゆーのはCnCの実行エンジンが善きに計らってくれるです。