2016-04-30 10 views
0

私は24ビット幅のブロック内でビットオーダーを変更するOpenCLカーネルを持っています。3バイトブロックで動作するOpenCLカーネル

これを実現するための最初の試みはbuffersize/3スレッドを作成することですが、何とか私のOpenClカーネルはCPU(2 GHz Intel Core i7)上で同じアルゴリズムとして遅く動作します。

typedef unsigned char uint8_t; 

__kernel void decode(
    __global uint8_t* in, 
    __global uint8_t* out, 
    const unsigned int count) { 
    int i = get_global_id(0)*3; 

    if(i<count){ 
     out[i]=in[i]; 
     out[i+1]=(in[i+1]&0b00001111)<<4|(in[i+2]&0b11110000)>>4; 
     out[i+2]=(in[i+2]&0b00001111)<<4|(in[i+1]&0b11110000)>>4; 
    } 
} 

このカーネルは、この方法と呼ばれている:

count = buffersize/3; // buffersize is approx. 6 to 8 MB 
error = clEnqueueNDRangeKernel(
     commands, 
     koDecode, 
     1, 
     NULL, 
     &count, 
     NULL, 
     0, 
     NULL, 
     NULL); 

はそれを行うには良い方法はありますか?

答えて

1

アルゴリズムで達成しようとしていることを理解していませんが、CLベクトルを使用してください。次の行の中の何か:

__kernel void decode(
      __global uchar3* in, 
      __global uchar3* out, 
      const unsigned int count) 
{ 
    int i = get_global_id(0); 
    out[i] = out[i].zyx; 
} 
+0

Intelのシングル操作とSIMDに5倍の密度を合わせるためにuchar16を使用できます。 –

+1

OPコードとまったく同じではありません。あなたは真の24ビット要素に取り組んでいるうちに、32ビット要素で操作しています。 'sizeof(uchar3)= 4' – DarkZeros

1

inほとんどのコンパイラにout「かもしれない」ポイントは、グローバル変数をキャッシュしていないので、これは、より速くなることがあります。そうしない、また

__kernel void decode(
    __global uint8_t* in, 
    __global uint8_t* out, 
    const unsigned int count) { 
    int i = get_global_id(0)*3; 

    if(i<count){ 
     out[i]=in[i]; 
     uint8_t t[2]; 
     t[0] = in[i+1]; 
     t[1] = in[i+2]; 
     out[i+1]=(t[0]&0b00001111)<<4|(t[1]&0b11110000)>>4; 
     out[i+2]=(t[1]&0b00001111)<<4|(t[0]&0b11110000)>>4; 
    } 
} 

を必要な量の作業項目を常に起動する場合は、実際にはi<countチェックが必要です。

関連する問題