有没有更好的方法来存储一对整数?

时间:2012-06-12 14:18:26

标签: c cuda

我很抱歉,如果这是非常基本的,但我仍然在学习我在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时解析它们但是我想知道是否有更好的方法来创建这个列表列表?

4 个答案:

答案 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);
}