gpt4 book ai didi

c++ - 结构和包含相同字节的原始变量哪个更快?

转载 作者:行者123 更新时间:2023-12-05 09:25:46 24 4
gpt4 key购买 nike

下面是一段代码示例:

#include <stdint.h> 
#include <iostream>

typedef struct {
uint16_t low;
uint16_t high;
} __attribute__((packed)) A;

typedef uint32_t B;

int main() {
//simply to make the answer unknowable at compile time
uint16_t input;
cin >> input;
A a = {15,input};
B b = 0x000f0000 + input;
//a equals b
int resultA = a.low-a.high;
int resultB = b&0xffff - (b>>16)&0xffff;
//use the variables so the optimiser doesn't get rid of everything
return resultA+resultB;
}

resultA 和 resultB 计算完全相同的东西 - 但哪个更快(假设您在编译时不知道答案)。

我尝试使用 Compiler Explorer 来查看输出,我得到了一些东西 - 但无论我尝试什么,任何优化都比我聪明并优化了整个计算(起初,它优化了所有东西,因为它没有被使用) - 我尝试使用 cin 使答案在运行时不可知,但后来我什至无法弄清楚它是如何得到答案的(我认为它仍然设法在编译时弄清楚?)

这是没有优化标志的 Compiler Explorer 的输出:

        push    rbp
mov rbp, rsp
sub rsp, 32
mov dword ptr [rbp - 4], 0
movabs rdi, offset std::cin
lea rsi, [rbp - 6]
call std::basic_istream<char, std::char_traits<char> >::operator>>(unsigned short&)
mov word ptr [rbp - 16], 15
mov ax, word ptr [rbp - 6]
mov word ptr [rbp - 14], ax
movzx eax, word ptr [rbp - 6]
add eax, 983040
mov dword ptr [rbp - 20], eax
Begin calculating result A
movzx eax, word ptr [rbp - 16]
movzx ecx, word ptr [rbp - 14]
sub eax, ecx
mov dword ptr [rbp - 24], eax
End of calculation
Begin calculating result B
mov eax, dword ptr [rbp - 20]
mov edx, dword ptr [rbp - 20]
shr edx, 16
mov ecx, 65535
sub ecx, edx
and eax, ecx
and eax, 65535
mov dword ptr [rbp - 28], eax
End of calculation
mov eax, dword ptr [rbp - 24]
add eax, dword ptr [rbp - 28]
add rsp, 32
pop rbp
ret

我也会发布 -O1 输出,但我无法理解它(我对低级汇编的东西很陌生)。

main:                                   # @main
push rax
lea rsi, [rsp + 6]
mov edi, offset std::cin
call std::basic_istream<char, std::char_traits<char> >::operator>>(unsigned short&)
movzx ecx, word ptr [rsp + 6]
mov eax, ecx
and eax, -16
sub eax, ecx
add eax, 15
pop rcx
ret

需要考虑的事情。虽然对整数进行操作稍微困难一些,但与结构相比,简单地将其作为整数访问更容易(我认为你必须用位移位转换?)。这有什么不同吗?

这最初是在内存上下文中出现的,我看到有人将内存地址映射到具有低位和高位字段的结构。我认为这不可能比简单地使用正确大小的整数并在需要低位或高位时进行位移更快。在这种特定情况下 - 哪个更快?

[为什么我把C加到标签列表里了?虽然我使用的示例代码是在 C++ 中,但结构与变量的概念也非常适用于 C]

最佳答案

除了某些 ABI 要求以不同于整数的方式传递结构这一事实之外,不会有任何区别。

现在,两个 16 位整数和一个 32 位整数之间存在重要的语义差异。如果你添加到低 16 位 int,它不会“溢出”到高位,而如果你添加到 32 位 int 的低 16 位,它会。这种可能行为的差异(即使您自己“知道”它不会在您的代码中发生)可能会改变您的编译器生成的汇编代码,并影响性能。

如果没有实际测试或对实际确切问题的完整描述,将无法知道这两者中哪一个会导致更快的结果。所以这是一个折腾。

这意味着唯一真正关心的是 ABI。这意味着,如果不对整个程序进行优化,采用 struct 的函数和采用具有相同二进制布局的 int 的函数将对数据位置有不同的假设。

但这只对按值的单个参数有影响。

90/10 规则适用; 90% 的代码运行时间少于 10%。这很可能不会对您的关键路径产生影响。

关于c++ - 结构和包含相同字节的原始变量哪个更快?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75097238/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com