如何编写包装函数以便编译器高效地优化它?
How to write wrapper function so that compiler efficiently optimize it?
我有一个函数可以在 returning link 列表的下一个节点之前进行基本错误检查:
Node *next_node(Node *n) {
switch(type(n)){
case A:
case B:
.
.
case N:
return n->next;
default:
exit(1); //This is just a representation of my code handling error scenario.
}
}
在它上面有更多的包装函数,它们根据上述函数的 return 值做某些事情。
这些包装函数在我的整个代码库中被广泛使用。太多了,当我 运行 分析器时,我发现它们是耗时的例程。
这对我来说确实有意义,因为从不同的代码区域对这些函数进行了数千次函数调用,并且由于函数调用开销 and/or 指令缓存未命中,如此数量的调用肯定会花费时间。
我也知道编译器会围绕这些进行一些优化,以便在生成汇编代码时可以内联它们。由于当前的实现方式,它似乎无法正常工作。
那么,我的问题是:
- 编写此类包装函数以使编译器可以优化它们以缩短 运行时间的常用方法是什么?
- 其他公司如何在他们的代码库中处理这种情况?
注意1:上面的代码只是为了表示,整个代码库中有很多这样的包装函数。因此,如果有人对改进由于包装函数导致的 运行time 问题有任何想法,应该分享这个想法。
注意 2:我使用 gcc 作为编译器,我的代码库完全是 C 语言。
所以您似乎处于低级优化的正确情况下,因为您已经分析了您的代码并发现了一个耗时的函数。
假设您已经使用了编译器的更高优化级别,那么不好的部分是没有针对此类问题的通用答案。我只能在这里给你一些提示:
- 哪里有多余的操作?如果是,你可以尝试确保你只做一次
- 是否存在可以展开的复杂循环?收获不大,但以更长的代码为代价进行了一些测试
- 汇编代码是一个选项吗?如果是你可以尝试用汇编语言编写全部或部分功能
但您可以(应该?)也想知道是否:
- 您的应用程序的总体结构是正确的 - 如果您能够设法减少调用函数,您将花费更少的时间...
- 您确实需要生产代码中的测试。如果它们是断言而不是测试,则它们应该只在测试和调试版本中有条件地包含在
#ifdef
中。
我有一个函数可以在 returning link 列表的下一个节点之前进行基本错误检查:
Node *next_node(Node *n) {
switch(type(n)){
case A:
case B:
.
.
case N:
return n->next;
default:
exit(1); //This is just a representation of my code handling error scenario.
}
}
在它上面有更多的包装函数,它们根据上述函数的 return 值做某些事情。
这些包装函数在我的整个代码库中被广泛使用。太多了,当我 运行 分析器时,我发现它们是耗时的例程。 这对我来说确实有意义,因为从不同的代码区域对这些函数进行了数千次函数调用,并且由于函数调用开销 and/or 指令缓存未命中,如此数量的调用肯定会花费时间。
我也知道编译器会围绕这些进行一些优化,以便在生成汇编代码时可以内联它们。由于当前的实现方式,它似乎无法正常工作。
那么,我的问题是:
- 编写此类包装函数以使编译器可以优化它们以缩短 运行时间的常用方法是什么?
- 其他公司如何在他们的代码库中处理这种情况?
注意1:上面的代码只是为了表示,整个代码库中有很多这样的包装函数。因此,如果有人对改进由于包装函数导致的 运行time 问题有任何想法,应该分享这个想法。
注意 2:我使用 gcc 作为编译器,我的代码库完全是 C 语言。
所以您似乎处于低级优化的正确情况下,因为您已经分析了您的代码并发现了一个耗时的函数。
假设您已经使用了编译器的更高优化级别,那么不好的部分是没有针对此类问题的通用答案。我只能在这里给你一些提示:
- 哪里有多余的操作?如果是,你可以尝试确保你只做一次
- 是否存在可以展开的复杂循环?收获不大,但以更长的代码为代价进行了一些测试
- 汇编代码是一个选项吗?如果是你可以尝试用汇编语言编写全部或部分功能
但您可以(应该?)也想知道是否:
- 您的应用程序的总体结构是正确的 - 如果您能够设法减少调用函数,您将花费更少的时间...
- 您确实需要生产代码中的测试。如果它们是断言而不是测试,则它们应该只在测试和调试版本中有条件地包含在
#ifdef
中。