Boost.Act

Boost.Act という革命的なライブラリを発見しまし,ゾクゾクとしたのでご紹介します.

Boost.Act is a C++ library which introduces STL-style algorithms that may be toggled to run in parallel or serially, and which provides tools for creating and working with parallelable algorithms, asynchronous function calls, active objects, and atomic objects, all with implementations adjustable via policies.

https://boost-consulting.com:8443/trac/soc/export/1786/boost/soc/2006/concurrency/tags/postfinal_untested/doc/html/index.html

STL スタイルのアルゴリズムの並列実行と直列実行をテンプレートで切り替えることが可能なライブラリです.手動マルチスレッド・プログラミングの経験者であれば,実際に試すことなくBoost.Act を読むだけでこのライブラリの凄さが感じられると思います.

以下,いくつか引用してみますが,実際に試していないので残念ながら実用的なレポートはできません.実際の使用感はどんな感じなんでしょうね?このライブラリがリリースしたら C++ に対する人々の眼差しは良い方向に変わるでしょうか…変わって欲しいと思う mrkn でした.

並列コピー

STL の copy と同じセマンティクスで並列コピーを実現できるようです.実際に並列化されるかどうかは,イテレータが RandomAccess か否か,シーケンスの value_type が parallel safe か否かなどで決定されるようです.並列実行できない状況では,::std::copy が使用される実装になっています.

#include <boost/act/algorithm.hpp>

#include <deque>
#include <vector>

int main()
{
  using std::vector;
  using std::deque;
  using boost::act::copy;

  // Source range of 100 elements, each having the value 5
  vector< int > source( 100, 5 );

  //Target range
  deque< long > target( 100 );

  // Uses ::boost::act::copy to copy from source to target
  copy( source.begin(), source.end(), target.begin() );
}

並列 for_each

次は ::std::for_each の並列版です.ベクタの各要素をインクリメントする関数オブジェクトを使用しています.関数オブジェクトが boost::act::parallel_safe を継承することで,並列実行できるようになります (もちろんイテレータがランダムアクセス可能でなければならない).

#include <boost/act/algorithm.hpp>
#include <boost/act/parallel_safe.hpp>

#include <vector>

struct increment
  : boost::act::parallel_safe
{
  void operator ()( int& target ) const
  {
    ++target;
  }
};

int main()
{
  using std::vector;
  using boost::act::for_each;

  // Source range of 100 elements, each having the value 4
  vector< int > source( 100, 4 );

  // Uses ::boost::act::for_each to increment each element
  for_each( source.begin(), source.end(), increment() );
}

制御構造の並列化

制御構造も並列化できます.以下は,for 文を自動並列化するために導入された basic_for の使用例です.boost::lambda の for_ と同様のセマンティクスです.

#include <boost/act/algorithm.hpp>

#include <iostream>

struct output_for_var
  : boost::act::parallel_safe
{
  void operator ()( int index ) const
  {
    std::cout << index;
  }
};

int main()
{
  using boost::act::basic_for;
  using boost::act::for_var;
  
  basic_for( for_var = 0, for_var < 10, ++for_var )
  [
    output_for_var()
  ];
}

Active Object

C++ の通常のコード記述で Active Object を生成できてしまいますよ!

#include <boost/act/action.hpp>
#include <boost/act/active.hpp>

#include <iostream>

int main()
{
  using boost::act::action;
  using std::cout;
  using std::endl;

  // Note that int is encapsulated in an extra set of parenthesis
  BOOST_ACTIVE((int)) value = 0;

  value += 10;

  value = *-value;

  action< int > result = value + value;

  ++value;

  // result's value may not be calculated at this point

  // Output the result (forcing a wait)
  cout << "value after the calculation is completed: "
       << result->inactive_value() << endl;
}