計算機能 1.3 GPU 上の CUDA カーネルでグローバル メモリのメモリ スループットを向上させるには、一般に 2 つの手法があります。メモリーは合体にアクセスし、少なくとも 4 バイトのワードにアクセスします。最初の手法では、同じハーフ ワープのスレッドによる同じメモリ セグメントへのアクセスは、より少ないトランザクションに結合されますが、少なくとも 4 バイトのワードにアクセスすると、このメモリ セグメントは 32 バイトから 128 バイトに効果的に増加します。
更新: talonmies answer に基づくソリューション。グローバル メモリに unsigned char が格納されている場合に 1 バイト ワードではなく 16 バイト ワードにアクセスするには、通常、メモリ配列を uint4 にキャストすることによって uint4 ベクトルが使用されます。uint4 ベクトルから値を取得するには、以下のように uchar4 に再キャストできます。
#include <cuda.h>
#include <stdio.h>
#include <stdlib.h>
__global__ void kernel ( unsigned char *d_text, unsigned char *d_out ) {
int idx = blockIdx.x * blockDim.x + threadIdx.x;
extern __shared__ unsigned char s_array[];
uint4 *uint4_text = reinterpret_cast<uint4 *>(d_text);
uint4 uint4_var;
//memory transaction
uint4_var = uint4_text[0];
//recast data to uchar4
uchar4 c0 = *reinterpret_cast<uchar4 *>(&uint4_var.x);
uchar4 c4 = *reinterpret_cast<uchar4 *>(&uint4_var.y);
uchar4 c8 = *reinterpret_cast<uchar4 *>(&uint4_var.z);
uchar4 c12 = *reinterpret_cast<uchar4 *>(&uint4_var.w);
d_out[idx] = c0.y;
}
int main ( void ) {
unsigned char *d_text, *d_out;
unsigned char *h_out = ( unsigned char * ) malloc ( 16 * sizeof ( unsigned char ) );
unsigned char *h_text = ( unsigned char * ) malloc ( 16 * sizeof ( unsigned char ) );
int i;
for ( i = 0; i < 16; i++ )
h_text[i] = 65 + i;
cudaMalloc ( ( void** ) &d_text, 16 * sizeof ( unsigned char ) );
cudaMalloc ( ( void** ) &d_out, 16 * sizeof ( unsigned char ) );
cudaMemcpy ( d_text, h_text, 16 * sizeof ( unsigned char ), cudaMemcpyHostToDevice );
kernel<<<1,16>>>(d_text, d_out );
cudaMemcpy ( h_out, d_out, 16 * sizeof ( unsigned char ), cudaMemcpyDeviceToHost );
for ( i = 0; i < 16; i++ )
printf("%c\n", h_out[i]);
return 0;
}