gpt4 book ai didi

c - Linux内核代码优化

转载 作者:太空狗 更新时间:2023-10-29 12:10:24 25 4
gpt4 key购买 nike

来自 Understanding Linux Kernel 3rd edition在描述内核固定映射的章节中,有一个使用以下枚举器的函数-

Each fix-mapped linear address is represented by a small integer index defined in the enum fixed_addresses data structure:

 enum fixed_addresses {
FIX_HOLE,
FIX_VSYSCALL,
FIX_APIC_BASE,
FIX_IO_APIC_BASE_0,
[...]
_ _end_of_fixed_addresses
};

并给出这个枚举器,下面的函数将编译-

Fix-mapped linear addresses are placed at the end of the fourth gigabyte of linear addresses. The fix_to_virt( ) function computes the constant linear address starting from the index:

inline unsigned long fix_to_virt(const unsigned int idx)
{
if (idx >= _ _end_of_fixed_addresses)
_ _this_fixmap_does_not_exist( );
return (0xfffff000UL - (idx << PAGE_SHIFT));
}

现在,看看下面关于这个函数如何最终翻译成只有0xfffff000-(3 << PAGE_SHIFT)的解释。

Let's assume that some kernel function invokes fix_to_virt(FIX_IOAPIC_BASE_0). Because the function is declared as "inline," the C compiler does not generate a call to fix_to_virt( ), but inserts its code in the calling function. Moreover, the check on the index value is never performed at runtime. In fact, FIX_IOAPIC_BASE_0 is a constant equal to 3, so the compiler can cut away the if statement because its condition is false at compile time. Conversely, if the condition is true or the argument of fix_to_virt( ) is not a constant, the compiler issues an error during the linking phase because the symbol _ _this_fixmap_does_not_exist is not defined anywhere. Eventually, the compiler computes 0xfffff000-(3 << PAGE_SHIFT) and replaces the fix_to_virt( ) function call with the constant linear address 0xffffc000.

因此,代码的作者似乎依赖于一些假设,即如果我们有一个 if 语句,比较编译时定义的两个数字(假设 FIX_IO_APIC_BASE_0_ _end_of_fixed_addresses),从而得到结果在编译时知道,比 if语句肯定会被优化并从代码中删除。

Linux 内核代码如何假设?

此外,编写此类代码的动机是什么?如果作者希望函数被评估为 0xfffff000-(3 << PAGE_SHIFT)为什么不写0xfffff000-(3 << PAGE_SHIFT)而不是调用此函数?

最佳答案

这里其实有两个问题:

  • Linux 内核代码如何假定代码已从二进制文件中删除?简单的答案是编译环境(编译器等)保证了这一点。基本上,常量传播是一种简单且众所周知的编译器优化,在这种情况下,它可以很容易地检测到代码未被使用。
  • 为什么不直接拼出代码?原因很简单,就是可移植性和可读性。可移植性意味着这允许您针对新平台或 CPU 在一个地方调整功能。可读性意味着意图与此功能的可能文档一起传达,如果您只是将原始功能内容转储在那里,情况就不会如此。这类似于在代码中不使用“魔数(Magic Number)”的理由。

关于c - Linux内核代码优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47120814/

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