-2

我需要启动 N 个线程(在一个块中)

这是代码,'e' 是 1024b 上的一个大数字。我需要将它复制到gpu上并一点一点地读取它。

主机代码:

unsigned char *__e;
BIGNUM *e = BN_new();
unsigned char exp[128];

//      e
i = cudaMalloc( (void**)&__e, 128* sizeof(unsigned char) );
if(i != cudaSuccess)
    printf("cudaMalloc __e FAIL! Code: %d\n", i);

BN_bn2bin128B(e, exp);   // copy data in exp

for(i=0; i<128; i++)
    exp[i] = reverse(exp[i]);

i = cudaMemcpy( __e, exp, 128* sizeof(unsigned char), cudaMemcpyHostToDevice);
if(i != cudaSuccess)
    printf("cudaMemcpy __e FAIL! Code: %d\n", i);


unsigned char reverse(unsigned char b) {
 b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
 b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
 b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
 return b;
}

设备代码:

for(int i=0; i<1024; i++)
    if(ISBITSET(__e, i) == 1)
        //do something

标题:

#define ISBITSET(x,i) ((x[i>>3] & (1<<(i&7)))!=0)

不幸的是,ISBITSET 不接受与 __e 不同的任何内容,因此我无法检查 __e 本身的其他值

我该如何解决?或者,还有更好的方法?

4

1 回答 1

2

GPU 是 32 位机器,因此您需要一次处理 32 位的 1024 位,而不是 8 位。因此,您应该替换所有unsigned charunsigned int相应地调整值。

GPU 有一个快速 PTX 指令,用于一次反转 32 位,因此您可能希望在 GPU 上实现它。该指令称为brev. 要使用它,您需要添加内联 PTX,如下所示(未经测试):

asm("brev.b32 %0, %1;" : "=r"(dst_var) : "r"(src_var));

有关详细信息,请参阅 NVIDIA 的文档“在 CUDA 中使用内联 PTX 组件”。

for(int i=0; i<1024; i++)
    if(ISBITSET(__e, i) == 1)
        //do something

此代码可能存在性能问题。假设有 50% 的机会打开一个位,您只能获得 50% 的可能性能,因为一半的线程将不得不等待而另一半执行//do something. 我想不出解决方法。您可能还想启动线程而不是循环。

不幸的是,ISBITSET 不接受与 __e 不同的任何内容,因此我无法检查 __e 本身的其他值

你能详细说明一下吗?ISBITSET宏对我来说看起来不错,看起来它可以处理任何无符号字符数组,就是这样__e

于 2012-07-18T23:37:35.587 回答