我试图了解 ABI(比如 System V)和 C++ 标准的区别。因此,C++ 标准只是确定了合法的 C++,以便编译器可以将其转换为足够的汇编代码。然后 ABI 规范了这个汇编代码如何与 x86 架构交互?这是两者之间更高层次的比较吗?
我问的原因是对低延迟软件感兴趣,我想知道阅读 ABI 会包含多少价值?
The standard defines what a program should do based on the code that you write. The ABI defines how that is implemented for a particular platform so that code compiled in different runs (possibly by different compilers/version) can interact.
That is, when you write:
void f(int i) { std::cout << i; }
The standard defines the behavior: a call to that function will cause the printout of the value of the argument. The ABI determines how the assembly is generated so that the function can be called (how is the name of f
mangled?) the argument can be passed in (will the argument be somewhere in the stack? in a register?).
Regarding the bold part of the question... well, it depends. ABIs are heavy reads, and it is hard to read and understand them. But you should at least be familiar with some of the basics, like calling conventions (what is the cost of passing an object of type T
?)... Beyond that I would make that a reactive approach: profile and if you need to understand what is going on, the ABI might help.
Most programmers don't know the ABI for their platform and they live as happily. I particularly have gone back and forth a couple of times to understand some peculiarities of the behavior of programs.
对于您的直接问题:了解 ABI 将在一定程度上帮助您。但是 ABI 不会告诉您在特定的 C++ 应用程序中什么是有效的——例如,使用内联的效果——这可能是有益的,也可能是有害的。同样,在某些情况下,选择使用vector
与 C 风格的数组可能会带来好处,但在其他地方,差别很小,不值得从一个更改为另一个。
低延迟软件更多的是要了解编译器在一般情况下对某些特定代码的作用,而不是确切地知道 ABI 中的第 13.6.2 段关于 VTABLE 是如何组织的——当然,除非你是特定的代码编译直接受 VTABLE 布局的影响 - 大多数时候这不是问题(除了理解虚函数是间接调用,它可能比相应的直接调用慢一点,对于简单的函数会明显慢比函数的内联版本。
您当然关心诸如“使用多少个寄存器来传递参数”之类的事情,但是知道编译器是使用 R0、R1、R2 还是 R13、R14 和 R15 作为三个寄存器来传递参数并不重要。
最重要的是,无论您多么认为您了解编译器的功能,查看汇编器输出,通过分析器运行代码等,都会比阅读 ABI 规范告诉您更多的信息。请记住,在典型的代码中,90% 的时间花在 10% 的代码上。修复使用 0.001% 总运行时间的函数的“缓慢”可能是浪费精力。