Ada*_*vis 6 c performance shift compiler-optimization unions
考虑一下简单的代码:
UINT64 result;
UINT32 high, low;
...
result = ((UINT64)high << 32) | (UINT64)low;
Run Code Online (Sandbox Code Playgroud)
现代编译器会将其转换为真正的高位移位,还是将其优化为简单的副本到正确的位置?
如果没有,那么使用联合似乎比大多数人似乎使用的转变更有效.但是,让编译器优化它是理想的解决方案.
我想知道当他们需要额外的一点性能时我应该如何建议.
我编写了以下(希望有效)测试:
#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;
}
Run Code Online (Sandbox Code Playgroud)
运行未优化输出的差异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), %eax
> movl %eax, -16(%rbp)
Run Code Online (Sandbox Code Playgroud)
我不懂汇编,所以我很难分析它。然而,看起来非联合(顶部)版本上正在发生一些变化。
但-O2启用优化后,输出是相同的。因此生成了相同的代码,两种方式将具有相同的性能。
(Linux/AMD64 上的 gcc 版本 4.5.2)
带或不带联合的优化代码的部分输出-O2:
movq 8(%rsi), %rdi
movl $10, %edx
xorl %esi, %esi
call strtol
movq 16(%rbx), %rdi
movq %rax, %rbp
movl $10, %edx
xorl %esi, %esi
call strtol
movq %rbp, %rdi
mov %eax, %eax
salq $32, %rdi
orq %rax, %rdi
call func
Run Code Online (Sandbox Code Playgroud)
该代码段在该行生成的跳转之后立即开始if。
| 归档时间: |
|
| 查看次数: |
1805 次 |
| 最近记录: |