我有一个接受uint8_t *的CUDA内核函数。我想将计算浮点数写入此uint8_t *数组中的特定位置(指针起始位置后12个字节)。
这样做的正确方法是什么?如果我假设:
uint8_t* ptr = address of a properly initialized and allocated memory segment
然后以下导致内核崩溃:
float some_float = ...
*((float *) (ptr+12)) = some_float
我知道这可能不是这样做的正确方法,甚至可能是某些人的失礼......但也许有人可以给出一两个关于如何最好地解决这个问题的建议。
谢谢!
答案 0 :(得分:-2)
你如何写浮点值?
我已经在处理一个处理具有不同数据大小的多个对象的项目。我们希望将对象属性保留在链表中,但将数据存储在单个公共大缓冲区中。所以在这个缓冲区中我们有8位有符号整数,后跟一个32位浮点数,后跟无符号整数64位等等......显然除了第一个元素没有对齐以节省空间。因此,当我们想写一个值时,我们会这样做:
// Write float value to any position in your big buffer
float fValueToWrite = 10;
memcpy(ptr + 12, &fValueToWrite, sizeof(fValueToWrite));
当我们想要读取我们所做的值时:
// Read the float from any unalign position of your big buffer
float fReadValue = 0;
memcpy(&fReadValue, ptr + 12, sizeof(fReadValue));
诀窍是使用不关心从非字边界读取的memcpy。
但如果我们这样做,请阅读:
float buffer[256] = {0};`
uint8_t* ptr = (uint8_t *)buffer;
float fCrashReadValue = *((float *)(ptr + 11));
可能导致处理器上的对齐错误不支持从11可被整除的边界读取( LoL实际上它是素数)。因此,如果你的CPU在这种情况下是32位,只要ptr
指向分配的缓冲区而不是另一个可能没有正确对齐的指针,12就是有效边界。
根据经验,我可以告诉您,我使用的许多ARM处理器都会使用非边界地址进行故障。但x86(英特尔)处理器将悄然重新调整惩罚性能。
希望它能帮到你:)