0
0

More than 3 years have passed since last update.

Boost LambdaとCUDA/GPUについての雑感

Last updated at Posted at 2020-08-17

ラムダ式は無名関数を提供する機能。
→ 個人的には、「いかに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

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0