ラムダ式は無名関数を提供する機能。
→ 個人的には、「いかにforループ式を書かないか」というコンセプトの1つ。
思えば、CUDA/GPU/Thrustも、いかに「C/C++的なforループを書かないか」という設計になっているとも言える。
例えば、CUDAのコードを見てみる。。
1 void sumOnCPU(float *A, float *B, float *C, const int N)
2 {
3 for (int idx = 0; idx < N; idx++)
4 {
5 C[idx] = A[idx] + B[idx];
6 }
7 }
8 __global__ void sumOnGPU(float *A, float *B, float *C, const int N)
9 {
10 int i = blockIdx.x * blockDim.x + threadIdx.x;
11
12 if (i < N) C[i] = A[i] + B[i];
13 }
行列Aと行列Bの和を取る、という処理は同じだが、12行目でforループが無くなっている。。
Thrustのコードの切れはしを見てみる。。。
1 // 32Mの乱数をCPUで生成
2 thrust::host_vector h_vec(1024 << 20);
3 std::generate(h_vec.begin(), h_vec.end(), rand);
4
5 // CPU(h_vec)からGPU(d_vec)へデータを転送
6 thrust::device_vector d_vec = h_vec;
7
8 // GPUでソートする
9 thrust::sort(d_vec.begin(), d_vec.end());
10
11 // ソートしたデータをCPU(h_vec)へ転送
12 thrust::copy(d_vec.begin(), d_vec.end(), h_vec.begin());
forループが無い。。繰り返しの表現にはループの他に、リスト(ここではvector)を使う方法がある。
ここからが本題のBoost Lambda。
1#include
2#include
3#include
4#include
5using namespace std;
6using namespace boost;
7
8int main()
9{
10 using namespace boost::lambda;
11
12 int init_v[] = {-25,-15,0,25,15};
13 vector v( init_v, init_v+5 );
14
15
16 for_each( v.begin(), v.end(), (cout << _1 << ',') );
17 cout << endl;
18
19 for_each( v.begin(), v.end(), (_1 += 13) );
20
21 for_each( v.begin(), v.end(), (cout << _1 << ',') );
22 cout << endl;
23
24 vector::iterator it =
25 adjacent_find( v.begin(), v.end(), (_1 > _2) );
26 cout << *it << " is more than " << *(it+1) << endl;
27
28 replace_if( v.begin(), v.end(), (_1 < 0 || 20 < _1), 0 );
29
30 for_each( v.begin(), v.end(), (cout << _1 << ' ') );
31 cout << endl;
32
33 return 0;
34}
16-17行目で全要素を表示
19行で全要素に13を足す
21-22行目で全要素(結果)を表示
16 for_each( v.begin(), v.end(), (cout << _1 << ',') );
17 cout << endl;
18
19 for_each( v.begin(), v.end(), (_1 += 13) );
20
21 for_each( v.begin(), v.end(), (cout << _1 << ',') );
22 cout << endl;
28行目で1以上20以下の要素は0にする
28 replace_if( v.begin(), v.end(), (_1 < 0 || 20 < _1), 0 );
$ ./a.out
-25,-15,0,25,15,
-12,-2,13,38,28,
38 is more than 28
0 0 13 0 0
ラムダ式の利点
■ 多くの小さな関数オブジェクトを生成しなくともすむ。
■ コード中に関数オブジェクトが散乱するのを防ぐ
■ コード量が減る。可読性が増す。
■ なんか響きがいい (`ー´)b