将浮点数写入uint8_t*位置

Writing a float to a uint8_t* location

本文关键字:位置 uint8 浮点数      更新时间:2023-10-16

我有一个CUDA内核函数接受uint8_t*。我想写一个计算float到这个uint8_t*数组的特定位置(指针开始位置后12字节)。

正确的做法是什么?如果我假设:

uint8_t* ptr = address of a properly initialized and allocated memory segment

那么下面的命令会导致内核崩溃:

float some_float = ...
*((float *) (ptr+12)) = some_float

我知道这可能不是正确的做法,甚至可能是失礼的…但是也许有人可以给一些关于如何最好地做到这一点的建议。

谢谢!

如何写float值?

我已经在处理不同数据大小的多个对象的项目上工作了。我们希望将对象属性保存在链表中,但将数据存储在单个公共大缓冲区中。所以在这个缓冲区中,我们有一个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位,在这种情况下,12是一个有效的边界,只要ptr指向已分配的缓冲区,而不是指向另一个可能没有正确对齐的指针。

根据经验,我可以告诉你,我使用过的许多ARM处理器在使用非边界地址时会出错。但是x86 (intel)处理器将悄悄地重新调整性能。

希望对你有帮助