在一次采访中,我被要求将big_to_little_endian()实现为宏。我用shift运算符实现了。但面试官希望我进一步优化这一点。我不能这样做。后来我google了&搜索但找不到它。有人可以帮助理解如何进一步优化此代码吗?
#define be_to_le (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24))
答案 0 :(得分:3)
他可能一直指的是使用16位操作来交换前两个字,然后使用8位操作来交换它们中的字节 - 保存一些指令,最简单的在联合中完成,尽管C技术上没有不喜欢它(但许多编译器会接受它),它仍然依赖于编译器,因为你希望编译器能够优化一些东西:
union dword {
unsigned int i;
union shorts {
unsigned short s0, s1;
union bytes {
unsigned char c0, c1, c2, c3;
} c;
} s;
};
union dword in = (union dword)x;
union dword temp = { x.s.s1, x.s.s0 };
union dword out = { temp.s.c.c1, temp.s.c.c0, temp.s.c.c3, temp.s.c.c2 };
甚至不是有效的C,但你明白了(我不认为编译器会发出我希望它会发出的东西)。
或者您可以保存操作,但引入数据依赖性,因此可能运行得更慢。
temp = (x << 16) | ( x >> 16)
out = ((0xff00ff00 & temp) >> 8) | (0x00ff00ff & temp) << 8)
最好只使用编译器内在函数,因为它映射到单个bswap
指令。