我很抱歉,如果这是非常基本的,但我仍然在学习我在C中可以做的所有事情,并且无法弄清楚如何做到这一点。
我在程序中创建了一对int,然后需要存储它们。到目前为止我一直在做的方法是创建一个结构:
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时解析它们但是我想知道是否有更好的方法来创建这个列表列表?
答案 0 :(得分:3)
不存储引用两个int
的内容,而是存储包含int
s副本的内容。
struct list_el {
int val; //first value
int val2; //second value
struct list_el * next;
};
typedef struct list_el item;
有时最好保留一个引用,有时最好保留一个值。根据您的尝试,使用正确的工具进行工作。
顺便说一下,你的引用控制结构只包含对short
的引用。要真正保留对int
的引用,您需要
struct list_el {
int *val; //reference to first value
int *val2; //reference to second value
struct list_el * next;
};
typedef struct list_el item;
请注意,如果您持有引用,则在处理struct引用之前,程序的其余部分不应丢弃引用的内存,以防止访问不再与程序关联的内存(这是一个错误)。 / p>
如果您不想使用类似构造的列表,还有其他技术。
int val[2] = { 1, 2 };
将存储两个int
,但只有两个整数。
int val[2][9];
将存储九对两个int
,并且可以很容易地表示为
int val[9][2];
当然,还有旧待机
int val = 3;
int val2 = 4;
答案 1 :(得分: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函数时不要忘记检查错误。
答案 2 :(得分:1)
如何使用二维数组?
int pairs[30][2];
pairs[0][0] = 10;
pairs[0][1] = 5;
// etc.
我必须测试它,但我认为我测试了它,你甚至可以做类似的事情
int pairs[][2] = {{10, 5}, {20, 40}, ...};
用于初始化。
注意:如果您知道提前有多少对,并且数字不会增长/缩小(大量),则此方法很有效。如果您的对数量变化很大,那么坚持使用结构列表并使用Edwin的答案从长远来看可能会更好。
答案 3 :(得分:1)
拥有一个二维数组是一个很好的解决方案,但我会回答你好像保留你的struct解决方案。
在结构中存储短整数没有任何问题,但我不会将值存储为short *。对我来说,不需要动态分配内存,因为你需要一个新的结构。
您可以使用一组结构来存储此数据。以下是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);
}