因此,我必须处理一些结构数据,这些数据必须以一种奇怪的方式压缩才能用于MPI_Send/Recv。
没有办法将它轻松地转换为指向我想要操作的已知类型的指针,然后进行索引(因为我已经将结构压缩到了连续的数据中,所以不能假设任何关于对齐的内容),所以我必须使用指针算术来完成它。问题是,为了与MPI保持一致,此数据被指定为void*,void*上的指针运算是非法的。
我的问题主要是风格上的:有比强制转换为char*然后进行指针运算更好的方法吗取一个空位*,铸造成焦炭*,对它做我的事情,然后再铸造回空位*,效率考虑因素是什么?我无法想象指针转换会非常昂贵。
再见,非常感谢。
指针强制转换是完全免费的。做吧。
具有类型的指针完全是语言级别的概念。当你进入硬件级别时,指针只是一个碰巧用作内存地址的整数。
当抛出指针时,确实必须小心严格的别名,但我认为char *
被定义为安全的。
[好吧,在某些架构中,有些情况下,指针除了"只是整数"之外还有特殊处理,但你可能会忽略这些。还有一些ABI中,不同的指针类型是不同的(例如FDPIC),但这也是其他人的问题。]
您的解决方案是合理的。很多次我都做过这样的事情:
void handle_raw(void* data) {
// Use a uint8_t so pointer arithmetic is at a byte-level.
uint8_t* p = data;
uint16_t value;
// Read a 2-byte value at an arbitrary offset.
value = *(uint16_t*)(p + 0x42);
// Write a 2-byte value at an arbitrary offset.
*(uint32_t*)(p + 0x12) = 0xDEADBEEF;
}
当然,您应该使用常量作为偏移量,并执行适当的边界检查。
您需要自己打包缓冲区有什么特殊的原因吗?在MPI操作之前,您真的压缩了连续缓冲区中的数据吗?如果是这样的话,你的压缩加传输时间必须比简单地进行传输时间低。如果是这样的话,那么我认为这是一个很好的理由。
如果您实际上只为MPI操作打包在一个连续的缓冲区中,那么解决问题的更好方法是停止自己打包数据,而是使用MPI派生的数据类型。
您可以使用类似于"MPI派生的数据类型示例"的内容进行web搜索,并获得比我在这里简要编写的内容更好的解释。