CUDA数据读取

  • 1 replies
  • 119 views
CUDA数据读取
« 于: 十二月 02, 2019, 12:46:15 am »
1. 我的数据通过函数GetData从硬件设备采集而来
GetData(&buffer, &BufferSize, &handle);
通过GetData函数可以得到一个数据块的首地址buffer的和数据块大小BufferSize

2. 我通过cudaMalloc分配了内存dev_a、dev_b。用cudaMemcpy将数据从主机拷贝到dev_a

// Allocate GPU buffers for one vectors (one input, one output).
cudaStatus = cudaMalloc((void**) &dev_a, size * sizeof(int));

cudaStatus = cudaMalloc((void**) &dev_b, size * sizeof(int));

cudaStatus = cudaMemcpy(dev_a, buffer, size * sizeof(int), cudaMemcpyHostToDevice);

3. 由于buffer中的数据有一定的结构,2个字节才能表示一个完整的数值(小端序)

问题:我如何才能在核函数中读取2个字节的内容,并返回给主机打印输出呢?

附件为数据的格式

Re: CUDA数据读取
« 回复 #1 于: 十二月 02, 2019, 04:35:37 pm »
1. 我的数据通过函数GetData从硬件设备采集而来
GetData(&buffer, &BufferSize, &handle);
通过GetData函数可以得到一个数据块的首地址buffer的和数据块大小BufferSize

2. 我通过cudaMalloc分配了内存dev_a、dev_b。用cudaMemcpy将数据从主机拷贝到dev_a

// Allocate GPU buffers for one vectors (one input, one output).
cudaStatus = cudaMalloc((void**) &dev_a, size * sizeof(int));

cudaStatus = cudaMalloc((void**) &dev_b, size * sizeof(int));

cudaStatus = cudaMemcpy(dev_a, buffer, size * sizeof(int), cudaMemcpyHostToDevice);

3. 由于buffer中的数据有一定的结构,2个字节才能表示一个完整的数值(小端序)

问题:我如何才能在核函数中读取2个字节的内容,并返回给主机打印输出呢?

附件为数据的格式

这是一个好问题。的确不能直接读取,例如图中的,TRG_OPTIONS字段,因为它是2B大小,却从offset 1开始的。而CUDA却有对齐性的要求(2B读取应当对齐到2B的边界)。

同时我也不建议对你图中的数据结构使用bit-field, 以避免可能存在的对齐方面的问题。

不如这样,对所有的每个横行使用uint32_t,然后对于需要的字段,手工shift + mask一下,
例如说:
TRG可以等于( v >> 8 ) & 0xffff

再例如说:
SAMPLE_X可以等于(v >> 16) & 0x3ffff(或者0x0ffff, 根据channel的不同)。

这里注意是SAMPLE_X这种能对齐到16-bit(2B)边界的,你也可以用uint16_t读取,从而规避一次shift。

但是需要指出的是,CUDA能将shift + mask编译成专门的BFE指令(位抽取),你读取16-bit,然后规避一次shift可能并无意义的,反而多了一次访存过程。

所以最终建议的解决方案:按行读取,手工移位+mask得到各个字段。
« 最后编辑时间: 十二月 02, 2019, 11:28:15 pm 作者 屠戮人神 »