我需要在 C 中对两个指针进行超高性能交换(地址,而不是它们指向的内容)。我知道地址是对齐的(16 的倍数)并且是连续的,我已经检查过这在每次执行中都会保留。代码如下:
Nodo a __attribute__((aligned(8))), b __attribute__((aligned(4)));
Nodo *nodo_superior __attribute__((aligned(4)));
nodo_superior = &a;
Nodo * nodo_actual __attribute__((aligned(4)));
nodo_actual=&b;
printf("%ld %ld\n", nodo_superior, nodo_actual);
控制台上的结果如下(请注意第一个地址应该“过度”对齐,以便下一个方法起作用):
140594404335200 140594404335216
现在要交换地址,我想更改每个指针的第 5 位:
nodo_superior ^= 16;
nodo_actual ^= 16;
但是,不幸的是,C 编译器不允许这样做,因为整数不能与指针值混合:这是错误,而不是警告。如果我尝试将指针包含在这样的 union 中:
union {
Nodo * nodo_actual;
int local_int;
} na;
想做一个这样的任务:
na.local_int ^= 16;
那么性能会下降,因为(我想)编译器不能对 nodo_actual 应用/推断优化,如果它在一个 union 中。 有什么想法可以强制编译器按照我的意愿行事吗?当然,我可以更改生成的汇编程序,但我认为这不是一个好的选择,
最佳答案
如果你想切换每个指针的第 5 位,你可以这样写:
nodo_superior = (Nodo *)((uintptr_t)nodo_superior ^ 16);
uintptr_t
是一种整数类型,(如果存在)保证能够保存指针值而不会丢失信息。
这是通过平面内存模型上的明显同构来完成的,因此它应该适合您(尽管先测试一下看看)。
此外,您应该使用 %p
来打印指针,而不是 %ld
,这会导致未定义的行为。打印 uintptr_t
see here
关于c - 在 C 中交换指针地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30891219/