首页 >后端开发 >C++ >为什么编译器优化会破坏这个 64 位交换功能?

为什么编译器优化会破坏这个 64 位交换功能?

DDD
DDD原创
2024-11-28 08:34:12530浏览

Why Does Compiler Optimization Break This 64-bit Swap Function?

为什么优化会降低这个函数的性能

在一次编程专业的大学讲座中,一位讲师提出了一个让学生感到困惑的函数:

inline u64 Swap_64(u64 x)
{
    u64 tmp;
    (*(u32*)&tmp)       = Swap_32(*(((u32*)&x)+1));
    (*(((u32*)&tmp)+1)) = Swap_32(*(u32*) &x);

    return tmp;
}

最初,该功能运行顺利,但在启用高优化级别后,它变得惰性。这种行为背后的原因在于严格别名规则的概念。

严格别名违规

提供的代码违反了严格别名规则,该规则规定对象只能是通过兼容的指针类型访问。在这种情况下,u32 和 u64 指针指向可能重叠的内存,但编译器假设它们代表不同的对象。这个假设允许它优化对临时变量 tmp 的赋值,从而使函数无效。

为什么会发生优化

允许编译器基于假设来优化代码关于指针行为。由于 u32 和 u64 是不同的类型,编译器假定它们不指向同一内存,并且通过 u32 指针所做的更改不会影响 tmp 的值。此优化导致了观察到的行为。

保留函数行为的解决方案

为了防止代码被优化,指针类型应与访问的数据类型匹配。一种方法是使用联合直接访问位:

typedef union
{
  uint32_t u32;
  uint16_t u16[2];
} U32;

uint32_t swap_words(uint32_t arg)
{
  U32 in;
  uint16_t lo;
  uint16_t hi;

  in.u32    = arg;
  hi        = in.u16[0];
  lo        = in.u16[1];
  in.u16[0] = lo;
  in.u16[1] = hi;

  return (in.u32);
}

通过使用联合,我们确保指针和数据类型兼容,防止编译器优化预期的更改。

以上是为什么编译器优化会破坏这个 64 位交换功能?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn