工会比现代编译器的转变更有效吗?

前端之家收集整理的这篇文章主要介绍了工会比现代编译器的转变更有效吗?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
考虑一下简单的代码
UINT64 result;
UINT32 high,low;
...
result = ((UINT64)high << 32) | (UINT64)low;

现代编译器会将其转换为真正的高位移位,还是将其优化为简单的副本到正确的位置?

如果没有,那么使用联合似乎比大多数人似乎使用的转变更有效.但是,让编译器优化它是理想的解决方案.

我想知道当他们需要额外的一点性能时我应该如何建议.

解决方法

我写了以下(希望有效)测试:
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>

void func(uint64_t x);

int main(int argc,char **argv)
{
#ifdef UNION
  union {
    uint64_t full;
    struct {
      uint32_t low;
      uint32_t high;
    } p;
  } result;
  #define value result.full
#else
  uint64_t result;
  #define value result
#endif
  uint32_t high,low;

  if (argc < 3) return 0;

  high = atoi(argv[1]);
  low = atoi(argv[2]);

#ifdef UNION
  result.p.high = high;
  result.p.low = low;
#else
  result = ((uint64_t) high << 32) | low;
#endif

  // printf("%08x%08x\n",(uint32_t) (value >> 32),(uint32_t) (value & 0xffffffff));
  func(value);

  return 0;
}

运行gcc -s的未优化输出的差异:

<   mov -4(%rbp),%eax
<   movq    %rax,%rdx
<   salq    $32,%rdx
<   mov -8(%rbp),%eax
<   orq %rdx,%rax
<   movq    %rax,-16(%rbp)
---
>   movl    -4(%rbp),%eax
>   movl    %eax,-12(%rbp)
>   movl    -8(%rbp),-16(%rbp)

我不知道集会,所以我很难对其进行分析.然而,看起来在非联合(顶级)版本上正如预期的那样发生了一些变化.

但是在启用优化-O2的情况下,输出是相同的.因此生成了相同的代码,两种方式都具有相同的性能.

(Linux / AMD64上的gcc版本4.5.2)

有或没有union的优化-O2代码的部分输出

movq    8(%rsi),%rdi
    movl    $10,%edx
    xorl    %esi,%esi
    call    strtol

    movq    16(%rbx),%rdi
    movq    %rax,%rbp
    movl    $10,%esi
    call    strtol

    movq    %rbp,%rdi
    mov     %eax,%eax
    salq    $32,%rdi
    orq     %rax,%rdi
    call    func

在if行生成跳转之后,片段立即开始.

猜你在找的C&C++相关文章