我这里有一些代码看起来很可怕,我想我永远不必再看到它或调试它(它将被完全不同的编程语言隐藏),以这种方式进行转换是否有开销?
void SubtractFloat (void *in, void *out){
int* a = (int*)in;
int* b = a++;
float c = * (float*)a;
float d = * (float*)b;
float* e = (float*)out;
*e = c - d;
}
(是的,我理解令人难以置信的代码违规行为,但有必要向上转发类型责任)
*顺便说一句,这可以变得更干净吗? (我什至会采纳汇编程序的建议)
最佳答案
在大多数现代 C 实现中,将一种类型的指针转换为另一种类型的指针的性能成本为零或可以忽略不计。更大的问题是在通用寄存器和浮点寄存器之间移动数据。
正如您所注意到的,您问题中的代码违反了 C 的严格别名规则,尽管您的 C 实现可能支持它。尽管如此,有两种选择:
如果in
、out
的环境以及您的C实现支持以float
方式访问内容,则使用:
float *fin = in, *fout = out;
fout[0] = fin[1] - fin[0];
如果不支持以 float
形式访问数据,则使用:
char *p = in;
float c, d, e;
memcpy(&d, p, sizeof d);
memcpy(&c, p + sizeof d, sizeof c);
e = c - d;
memcpy(out, &e, sizeof e);
请注意,虽然 memcpy
在 C 抽象机中名义上更差(它逐个复制字节),但良好的 C 实现将优化此代码。 (如果 in
和 out
的对齐不是问题,那么对于典型的处理器,一个好的编译器应该生成两个加载、一个减法和一个存储。如果对齐是考虑到,可能需要某种形式的未对齐加载和存储。但在任何情况下都需要它们。)
关于c - 在 C 中,转换指针有开销吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53658664/