2016-04-30 2 views
0

У меня есть ядро ​​OpenCL, которое изменяет порядок бит в блоках шириной 24 бит.Ядро OpenCL для работы с блоками 3 байта

Моя первая попытка реализовать это - создать потоки buffersize/3, но как-то мое ядро ​​OpenCl работает медленнее, чем тот же алгоритм на процессоре (2 ГГц 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

Может использовать uchar16, чтобы в 5 раз увеличить плотность в одной операции и SIMD Intel. –

+1

Точно не похоже на код OP. Вы работаете с 32-битными элементами, в то время как он работает с настоящими 24-битными элементами. 'sizeof (uchar3) = 4' – DarkZeros

1

Это может быть быстрее, так как out «может» точка in большинства компиляторов не кэшировать глобальные переменные:

__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, если вы всегда запускаете необходимое количество рабочих элементов.

Смежные вопросы