ラムダ式#
C++11 ラムダ式により、oneAPI スレッディング・ビルディング・ブロック (oneTBB) の parallel_for がはるかに使いやすくなります。ラムダ式を使用すると、関数オブジェクトを作成する面倒な作業をコンパイラーが実行できるようになります。
以下は、前の節の例をラムダ式で書き直したものです。ラムダ式は、前の節の例の関数オブジェクト ApplyFoo の宣言と構築の両方を置き換えます。
#include "oneapi/tbb.h"
using namespace oneapi::tbb;
void ParallelApplyFoo( float* a, size_t n ) {
parallel_for( blocked_range<size_t>(0,n),
[=](const blocked_range<size_t>& r) {
for(size_t i=r.begin(); i!=r.end(); ++i)
Foo(a[i]);
}
);
}[=] はラムダ式を示します。この式は ApplyFoo によく似た関数オブジェクトを作成します。a や n などのローカル変数がラムダ式の外側で宣言され、内側で使用される場合、それらは関数オブジェクト内のフィールドとして “キャプチャー“ されます。[=] は、キャプチャーが値によって行われることを指定します。代わりに [&] と記述すると、値を参照によってキャプチャーします。[=] の後には、生成された関数オブジェクトの operator() のパラメーター・リストと定義が続きます。コンパイラーのドキュメントには、ラムダ式やそのほかに実装された C++11 機能の詳細が記載されています。ラムダ式はテンプレート・ライブラリー全般を使用する強力な機能であるため、ここに記載できる以上の詳しい説明をぜひ一読ください。
コンパイラーでは、C++11 のサポートはデフォルトで無効になっています。次の表は、これを有効にするオプションを示しています。
環境 |
インテル® C++ コンパイラー・クラシック |
インテル® oneAPI DPC++/C++ コンパイラー |
|---|---|---|
Windows* システム |
|
|
Linux* システム |
|
|
さらにコンパクトにするため、oneTBB には連続した整数のレンジの並列ループを実行する parallel_for 形式が用意されています。式 parallel_for(first,last,step,f) は、リソースが許せば各 f(i) を並列に評価できることを除いて、for(auto i=first; i<last; i+=step)f(i) に似ています。step パラメーターはオプションです。前述の例を簡潔な形式で書き直すと次のようになります。
#include "oneapi/tbb.h"
using namespace oneapi::tbb;
#pragma warning(disable: 588)
void ParallelApplyFoo(float a[], size_t n) {
parallel_for(size_t(0), n, [=](size_t i) {Foo(a[i]);});
}コンパクト形式では、整数の一次元反復空間と次の節で説明する自動チャンク機能のみがサポートされます。