【问题标题】:Optimized code for big to little endian conversion大端到小端转换的优化代码
【发布时间】:2015-02-05 06:02:28
【问题描述】:

在一次采访中,我被要求将 big_to_little_endian() 实现为宏。我使用移位运算符实现。但面试官希望我进一步优化这一点。我做不到。后来我用谷歌搜索并搜索但找不到它。有人可以帮助了解如何进一步优化此代码吗?

#define be_to_le (((x) >> 24) | (((x) & 0x00FF0000) >> 8) | (((x) & 0x0000FF00) << 8) | ((x) << 24))

【问题讨论】:

  • 我觉得不错。也许他正在寻找一些要使用的 ASM 'shuffle' 指令?一个好的编译器不应该这样做吗?
  • 旁白:与其重新发明轮子,不如使用ntohl 或您的平台提供的等效项。写完答案后,您可能已经礼貌地添加了这一点:)
  • This answer 展示了使用编译器内在函数的最快方法。

标签: c optimization endianness


【解决方案1】:

他可能指的是使用 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 指令。

【讨论】:

    猜你喜欢
    • 2017-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-17
    • 2014-05-24
    • 1970-01-01
    相关资源
    最近更新 更多