对于 64 位除法,使用/和 有do_div什么区别?只是为了提高性能?它是否依赖于架构?
这个宏和这个模块中的函数的目的是优化。内核代码中的注释非常清楚:
/*
* do_div() is NOT a C function. It wants to return
* two values (the quotient and the remainder), but
* since that doesn't work very well in C, what it
* does is:
*
* - modifies the 64-bit dividend _in_place_
* - returns the 32-bit remainder
*
* This ends up being the most efficient "calling
* convention" on x86.
*/
Run Code Online (Sandbox Code Playgroud)
宏在内核中用于在单个步骤中计算商和余数,而不是标准 C 中的 2 个操作,可能会产生 2 个除法操作码。
事实上,Intel x86 CPU 用一条指令计算整数除法的商和余数。宏使用内联组件利用这一优势,而C编译器可能不能优化2个独立的计算与/和%成单个操作码。
在编写这段代码的时候,大多数编译器都没有,而且除法操作码非常昂贵,所以 Linus 决定使用一个特殊的函数来优化这个计算。
请注意,C 标准为此提供了一组函数(在 中声明<stdlib.h>):
div_t div(int numer, int denom);
ldiv_t ldiv(long int numer, long int denom);
lldiv_t lldiv(long long int numer, long long int denom);
Run Code Online (Sandbox Code Playgroud)
linux 内核针对的系统可能没有符合标准的编译器,并且肯定早于这些标准添加中的一些,因此它具有这些函数的自己版本作为宏,以及同一模块中的其他一些版本。