1

如果这是非常基本的,我很抱歉,但我仍在学习我可以在 C 中做的所有事情,但不知道如何做到这一点。

我在程序中创建了成对的整数,然后需要存储它们。到目前为止我一直在做的方式是创建一个结构:

struct list_el {
    short *val; //first value
    short *val2; //second value
    struct list_el * next;
};
typedef struct list_el item;

我可以在我的正常程序中很好地迭代列表,但我想将它发送给 Cuda,但我不确定如何将整个结构转移到 Cuda(我知道我可以引用它)。我想知道是否有另一种方法可以构造这些数据,所以也许是它的数组?我需要的格式只是简单的配对(例如 10:5、20:40 等)。我认为最坏的情况是我可以使用一个 char 字符串并将这些对作为字符,然后在主数组位于 Cuda 时解析它们,但我想知道是否有更好的方法来创建这个列表列表?

4

4 回答 4

3

不要存储引用两个ints 的内容,而是存储包含 s 副本的内容int

struct list_el {
    int val; //first value
    int val2; //second value
    struct list_el * next;
};
typedef struct list_el item;

有时最好保留一个引用,有时最好保留一个值。根据您尝试做的事情,使用正确的工具来完成这项工作。

顺便说一句,您的引用持有结构仅持有对shorts 的引用。要真正持有对ints 的引用,您需要

struct list_el {
    int *val; //reference to first value
    int *val2; //reference to second value
    struct list_el * next;
};
typedef struct list_el item;

请注意,如果您持有一个引用,则程序的其余部分不应在您处理结构引用之前处理该引用的内存,以防止访问不再与程序关联的内存(这是一个错误)。

如果您不想使用类似构造的列表,还有其他技术。

int val[2] = { 1, 2 };

将存储两个ints,但只有两个整数。

int val[2][9];

将存储九对两个ints,也可以很容易地表示为

int val[9][2];

当然,还有旧的备用

int val = 3;
int val2 = 4;
于 2012-06-12T14:22:39.113 回答
3

假设您可以使用两个单独的数组,并考虑如何在 CUDA 中使用/读取/写入它们,我将把数据安排在两个数组中,主要是由于内核中全局内存的合并访问。

int *h_val1, *h_val2; // allocate arrays in the host and initialize them

设 N 为数组的大小,在设备内存中分配数组

int *d_val1, *d_val2;
cudaMalloc( (void**) &d_val1, N * sizeof(int) );
cudaMalloc( (void**) &d_val2, N * sizeof(int) );

并将数据从主机复制到设备内存

cudaMemcpy(h_val1, d_val1, N * sizeof(int), cudaMemcpyHostoToDevice);
cudaMemcpy(h_val2, d_val2, N * sizeof(int), cudaMemcpyHostoToDevice);

配置并启动内核以运行与数组中的元素一样多的线程。

// kernel configuration
dim3 dimBlock = dim3 ( BLK_SIZE, 1, 1 );
dim3 dimGrid  = dim3 ( (N / BLK_SIZE) + 1 );

yourKernel<<<dimGrid, dimBlock>>>(d_val1, d_val2);

考虑到这一点,实现你的内核

__global__ void
yourKernel(int* val1, int* val2, N)
{
    // map from threadIdx/BlockIdx to index position
    int gid = threadIdx.x + blockIdx.x * blockDim.x;

   if (gid < N)
   {
        int r_val1 = val1[ idx ]; // load from global memory to register
        int r_val2 = val2[ idx ]; // load from global memory to register

        // do what you need to do with pair val1:val2
   }
}

调用 CUDA 函数时不要忘记检查错误。

于 2012-06-12T16:41:01.703 回答
1

只使用二维数组怎么样?

int pairs[30][2];

pairs[0][0] = 10;
pairs[0][1] = 5;
// etc.

我必须测试它,但我想我测试了它,你甚至可以做类似的事情

int pairs[][2] = {{10, 5}, {20, 40}, ...};

用于初始化。

注意:如果您提前知道将拥有多少双并且数量不会增长/缩小(大量),则此方法效果很好。如果您的配对数量变化很大,从长远来看,坚持使用结构列表并使用 Edwin 的答案可能会更好。

于 2012-06-12T14:22:54.573 回答
1

拥有一个二维数组是一个很好的解决方案,但我会像保留结构解决方案一样回答。

将短整数存储在结构中没有任何问题,但我不会将值存储在短 * 中。对我来说,动态分配内存是不值得的,因为您需要一个新结构。

你可以有一个结构数组来存储这些数据。这是一个固定大小的数组示例item

#include <stdio.h>

struct list_el {
    short val; //first value
    short val2; //second value
};
typedef struct list_el item;

item listA[20];

int main()
{
    listA[0].val = 1;
    listA[0].val2 = 2;

    printf("\n%i %i\n", listA[0].val, listA[0].val2);
    return 0
}

即使您提出您不会事先知道您将拥有多少个这些结构的论点,我也只会像这样为数组分配空间:

#include <stdio.h>
#include <stdlib.h>

struct list_el {
    short val; //first value
    short val2; //second value
};
typedef struct list_el item;

item * p_list_el,  * pCurStruct;

int main()
{
    int idx;

    /* p_list_el is the pointer to the array. Don't modify.
       pCurStruct can be modified to walk the array. */

    p_list_el = malloc(sizeof(item) * 20);

    for(idx=0, pCurStruct=p_list_el; idx < 20; idx++)
    {
        pCurStruct[idx].val = idx;
        pCurStruct[idx].val2 = idx + 1;
    }


    for(idx=0, pCurStruct=p_list_el; idx < 20; idx++)
    {
        printf("\n%i %i\n", pCurStruct[idx].val, pCurStruct[idx].val2);
    }

    free(p_list_el);
}
于 2012-06-12T15:18:48.743 回答