1

我遇到了 CUDA 的问题。我想制作一个小程序来计算字符数组中的字母。

我从文件中读取字母并保存到名为 N 的 int 变量中,读取了多少个字母。之后我malloc。

char *b_h, *b_d;
size_t size_char = N * sizeof(char);
b_h = (char *)malloc(size_char);

在 malloc 之后,我再次读取文件并将当前字母分配给 char 数组的元素(它有效):

int j=0;
while(fscanf(file,"%c",&l)!=EOF)
{
    b_h[j]=l;
    j++;
}

之后,我创建了一个 int 变量 (a_h) 作为计数器。

int *a_h, *a_d;
size_t size_count = 1*sizeof(int);
a_h = (int *)malloc(size_count);

好的,使用 CUDA:

cudaMalloc((void **) &a_d, size_count);
cudaMalloc((void **) &b_d, size_char);

从主机复制到设备:

cudaMemcpy(a_d, a_h, size_count, cudaMemcpyHostToDevice);
cudaMemcpy(b_d, b_h, size_char, cudaMemcpyHostToDevice);

设置块并调用 CUDA 函数:

int block_size = 4;
int n_blocks = N/block_size + (N%block_size == 0 ? 0:1);
square_array <<< n_blocks, block_size >>> (a_d,b_d,c_d, N);

从函数接收:

cudaMemcpy(a_h, a_d, size_count, cudaMemcpyDeviceToHost);
cudaMemcpy(b_h, d_d, size_char, cudaMemcpyDeviceToHost);

并打印计数:

printf("\Count: %d\n", a_h[0]);

它不起作用。在 char 数组中,我有一句话: Super testSuper test ; 我正在寻找 'e' 字母,我得到 a_h[0] = 1。问题出在哪里?

CUDA功能:

__global__ void square_array(int *a, char *b, int *c, int N)
{
const char* letter = "e";

int idx = blockIdx.x * blockDim.x + threadIdx.x;

if (idx<N) 
{
    if(b[idx] == *letter)
    {
        a[0]++;
    }
}
}

请帮我。

4

1 回答 1

2

我猜 N 足够小,以至于您的 GPU 能够并行启动所有线程。因此,您为数组中的每个字符启动一个线程。所有同时运行的线程看不到彼此的输出。相反,每个线程读取 a[0] 的值(即 0),并将其增加 1 并存储结果值 (1)。如果这是家庭作业,那将是教授想要传授的基本课程。

当多个线程同时在同一位置存储一个值时,未定义哪个线程将存储其值。在您的情况下,这无关紧要,因为所有存储值的线程都将存储值“1”。

一个典型的解决方案是让每个线程将值 0 或 1 存储在单独的位置(取决于是否存在匹配),然后在单独的步骤中将这些值相加。

您还可以使用原子增加操作。

于 2012-04-15T03:14:09.903 回答