ABI与C++标准

use*_*112 5 c++ cpu x86 assembly abi

我试图理解ABI(比如System V)和C++ Standard的不同之处.因此,C++标准只是确定合法的C++,以便编译器可以将其转换为适当的汇编代码.然后ABI规定此汇编代码如何与x86架构交互?是两者之间的较高级别比较吗?

我问的理由是对低延迟软件感兴趣我想知道阅读ABI会包含多少价值?

Dav*_*eas 6

该标准根据您编写的代码定义程序应该执行的操作.ABI定义了如何为特定平台实现,以便在不同运行中编译的代码(可能由不同的编译器/版本)进行交互.

也就是说,当你写:

void f(int i) { std::cout << i; }
Run Code Online (Sandbox Code Playgroud)

标准定义了行为:对该函数的调用将导致参数值的打印输出.ABI确定如何生成程序集,以便可以调用该函数(如何修改名称f?)参数可以传入(参数是否在堆栈中的某个位置?在寄存器中?).

关于问题的大胆部分......嗯,这取决于.ABI是重读,很难阅读和理解它们.但是你至少应该熟悉一些基础知识,比如调用约定(传递类型对象的成本是T多少?)......除此之外,我会把它作为一种被动的方法:profile,如果你需要了解什么正在进行中,ABI可能会有所帮助.

大多数程序员不知道他们的平台的ABI,他们生活愉快.我特别经常来回几次,以了解程序行为的一些特点.


Mat*_*son 5

直接问题:了解ABI会在某种程度上对您有所帮助.但ABI不会告诉你特定C++应用程序的效率如何 - 例如,使用内联的效果 - 这可能是有益的和有害的.类似地,vector在某些情况下,使用与C风格数组的选择可能会带来好处,但在其他地方,它的差别很小,因此不值得从一个转换到另一个.

低延迟软件更多的是要了解编译器在一般情况下使用某些特定代码所做的事情,而不是确切地知道ABI中关于如何组织VTABLE的第13.6.2段 - 除非当然,特定代码是编译直接受VTABLE布局的影响 - 大多数情况下它不是一个问题(除了理解虚函数是间接调用,它可能比相应的直接调用慢一点,而简单的函数会慢得多)而不是函数的内联版本.

您当然关心"使用多少个寄存器来传递参数"之类的事情,但是知道编译器是使用R0,R1,R2还是R13,R14和R15作为三个寄存器来传递参数的重要性要小得多.

最重要的是,无论你认为你理解编译器的作用有多少,查看汇编器输出,通过分析器运行代码等,都会比阅读ABI规范更多地告诉你.请记住,在典型代码中,90%的时间花在10%的代码上.修复使用总运行时间的0.001%的函数的"缓慢"可能是浪费精力.