2

我一直在使用 Valgrind 进行一些测试,以了解编译器如何翻译函数,并发现有时,由于未内联,与编写在同一源文件上的函数相比,编写在不同文件上的函数性能较差。

考虑到我有不同的文件,每个文件都包含与特定区域相关的功能,并且所有文件共享一个声明所有功能的通用标题,这是预期的吗?

为什么当它们写在不同的文件上时编译器不内联它们但是当它们在同一个页面上时呢?

如果此行为开始导致性能问题,建议采取什么措施,在编译之前手动将所有函数放在同一个文件中?

例子:

//source 1
    void foo(char *str1, char *str2)
    {
        //here goes the code
    }

//source 2
    void *bar(int something, char *somethingElse)
    {
        //bar code
        foo(variableInsideBar, anotherVariableCreatedInsideBar);
        return variableInsideBar;
    }

样品性能成本:

在不同的文件上:29920

两者都在同一个文件上:8704

对于更大的功能,它没有那么明显,但仍然会发生。

4

3 回答 3

2

如果您正在使用gcc,您应该尝试这些选项-combine-fwhole-program并在一次调用中将所有源文件传递给编译器。传统上不同的 C 文件是分开编译的,但是优化交叉编译单元(文件)变得越来越普遍。

于 2013-09-28T22:16:29.060 回答
1

编译器本身不能内联定义在不同翻译单元中的函数,因为它看不到这些函数的定义,即看不到这些函数的源代码。从历史上看,C 编译器(以及语言本身)是围绕独立翻译原则构建的。每个翻译单元都从源代码编译成目标代码,完全独立于其他翻译单元。只有在翻译的最后阶段,所有这些不相交的目标代码块才通过所谓的链接器组装成最终程序。但是在那个时候,在传统的编译器实现中,内联任何东西已经太晚了。

您可能知道,函数内联的语言级支持表明,为了使某个函数在某个翻译单元中“可内联”,它必须在该翻译单元中定义,即其主体的源代码应该对该翻译单元中的编译器。这一要求直接源于上述独立翻译原则。

许多现代编译器正在逐渐引入克服经典纯独立翻译限制的功能。它们实现了诸如全局优化之类的功能,这些功能允许跨翻译单元边界的各种优化。这可能包括内联其他翻译单元中定义的函数的能力。请查阅您的编译器文档,以了解它是否可以跨翻译单元内联函数以及如何启用此类优化。

默认情况下通常禁用此类全局优化的原因是它们会显着增加翻译时间。

于 2013-09-28T22:30:20.657 回答
-1

哇,你怎么注意到的。我认为那是因为你编译了一些东西,首先编译器将一个 c 文件转换为一个目标文件,而不查看任何其他文件。制作目标文件后,它不会应用任何优化。

我不认为它花费太多性能。

于 2013-09-28T21:46:45.033 回答