SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

マルチスレッドを意識しないマルチスレッド・ライブラリ「Intel Concurent Collections」がおもしろい

 動かしてみましょう、10個の"Hello, world"を同時に着火します。

list04
int main() {
  my_context ctx;
  const int steps = 10;
  cout << "--- let's start ---\n";
  for ( int n = 0; n < steps; ++n ) {
    ctx.tags.put(n); // 着火!!
  }
  cout << "--- all steps activated ---\n";
  ctx.wait();
  cout << "--- that's it. ---\n";
}

 コビトさんが8人いる僕のマシンでの実行結果はこうなりました。

 コビトさんたちがCnCの中で同時に働いている様子が伺えますね。

 itemの入出力を使った例もお見せしましょう。与えられた値の平方根を求めるだけの簡単なお仕事です。

 itemの集合CnC::item_collection<key,value>は辞書になっていて、keyに紐づいたvalueをget/putできます。

list05
#include <iostream>
#include <cmath>
#include <cnc/cnc.h>
using namespace std;

struct my_context;

struct my_step {
  int execute(const int& tag, 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> inputs;
  CnC::item_collection<int,double> outputs;

  my_context() : steps(*this), tags(*this), inputs(*this), outputs(*this) {
    tags.prescribes(steps, *this); // tags  は steps   に指示する
    steps.consumes(inputs);        // steps は inputs  を消費する
    steps.produces(outputs);       // steps は outputs を生産する
  }
};

int my_step::execute(const int& tag, my_context& ctx) const {
  double input;
  ctx.inputs.get(tag, input);
  ctx.outputs.put(tag, sqrt(input));
  return CnC::CNC_Success;
}

int main() {
  my_context ctx;
  const int steps = 10;
  // 入力をセットして
  for ( int tag = 0; tag < steps; ++tag ) {
    ctx.inputs.put(tag, static_cast<double>(tag));
  }

  // 着火
  for ( int tag = 0; tag < steps; ++tag ) {
    ctx.tags.put(tag);
  }
  ctx.wait(); // 完了を待って

  // 結果を取り出す
  for ( int tag = 0; tag < steps; ++tag ) {
    double input;
    ctx.inputs.get(tag, input);
    double result;
    ctx.outputs.get(tag, result);
    cout << "sqrt(" << input << ") = " << result << endl;
  }

}

 では次にちょっとした応用例、複利計算をやってみます。複利計算では"n年後の残高"は"(n-1)年後の残高に(1+利率)を掛ける"ことで得られます。なのでn番itemに"n年後の残高"を求めることにすれば、n番stepで"(n-1)番itemを読み(1+利率)を掛けてn番itemに書く"を行わせれば、こいつを数珠つなぎにすることでn年後の残高がn番itemから得られます。

list06
#include <iostream>
#include <cnc/cnc.h>

using namespace std;

struct my_context; // forward decl.

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); // tags は steps に 指示する
    steps.consumes(items);         // steps は items を消費する
    steps.produces(items);         // steps は items を生産する
  }
};

// n-1年の残高と利率からn年後の残高を求める
int my_step::execute(const int& n, my_context& ctx) const {
  // n 年後の残高は
  double result;
  ctx.items.get(n-1, result); // n-1 年後の残高に
  result *= (1.0 + ctx.rate); // 利率をかけたもの
  ctx.items.put(n, result);   // である
  return CnC::CNC_Success;
}

int main() {
  my_context ctx;
  ctx.rate = 0.05;           // 年利5%の定期預金に
  ctx.items.put(0, 10000.0); // 初年度に1万円預けて
  const int duration = 10;   // 10年間放置するとき

  // 1年後, 2年後, ... 10年後 の残高を求めよ!
  for ( int n = 1; n <= duration; ++n ) {
    ctx.tags.put(n); // ここでstepをkickする
  }
  ctx.wait(); // 終わるのを待って

  // 出力する
  for ( int n = 0; n <= duration; ++n ) {
    double balance;
    ctx.items.get(n, balance);
    cout << balance << endl;
  }
}

 んー...面白みに欠けますね。前段のstepが完了しないと後段のstepが動けない(ctx.items.get()でブロックする)ので、動いてるstepは1つだけなんですよね。

次のページ

この記事は参考になりましたか?

特集記事連載記事一覧

もっと読む

この記事の著者

επιστημη(エピステーメー)

C++に首まで浸かったプログラマ。Microsoft MVP, Visual C++ (2004.01~2018.06) "だった"りわんくま同盟でたまにセッションスピーカやったり中国茶淹れてにわか茶...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/7321 2013/09/03 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー