C++优化级别是否会影响Swig Python模块的性能
Does C++ optimisation level affect Swig Python module performance
我有一个大型Swig Python模块。C++包装器最终大约是320000个LoC(我想包括头)。我目前用-O1编译它,g++生成一个44MiB大小的二进制文件,编译它大约需要3分钟
如果我关闭优化(-O0),二进制文件的输出为40MiB,编译需要44秒。
用-O0编译包装器会严重损害python模块的性能吗?在我分析模块在不同优化级别的性能之前,有人以前做过这种分析吗?或者对它是否重要有任何见解吗?
-O0停用gcc执行的所有优化。优化也很重要。
因此,如果您的应用程序中没有太多知识,我可能会认为这会影响应用程序的性能。
通常使用的安全优化级别是-O2。
您可以在以下位置检查GCC执行的优化类型:http://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html.
但最后,如果你想确切地知道,你应该在不同的级别和概要进行编译。
无论SWIG模块与否,这都是错误的。即使使用gcc -O1
,也会出现许多优化,如果您阻止它们发生,您将错过这些优化。
您可以通过检查所选编译器生成的asm来检查差异。其中,我非常了解的那些将对SWIG生成的包装器有害:
-
死码消除:
void foo() { int a = 1; a = 0; }
使用-O1,这个完全没有意义的代码被完全删除:
foo: pushl %ebp movl %esp, %ebp popl %ebp ret
而对于-O0,它变成:
foo: pushl %ebp movl %esp, %ebp subl $16, %esp movl $1, -4(%ebp) movl $0, -4(%ebp) leave ret
-
在具有大量局部变量的函数中,寄存器分配将受到不利影响——大多数SWIG包装函数都会受到影响。不过,很难给出一个简洁的例子。
-
另一个例子是gcc为原型编译SWIG包装器的输出:
int foo(unsigned int a, unsigned int b, unsigned int c, unsigned int d);
使用
-O0
:生成Java_testJNI_foo: pushl %ebp movl %esp, %ebp subl $88, %esp movl 16(%ebp), %eax movl %eax, -48(%ebp) movl 20(%ebp), %eax movl %eax, -44(%ebp) movl 24(%ebp), %eax movl %eax, -56(%ebp) movl 28(%ebp), %eax movl %eax, -52(%ebp) movl 32(%ebp), %eax movl %eax, -64(%ebp) movl 36(%ebp), %eax movl %eax, -60(%ebp) movl 40(%ebp), %eax movl %eax, -72(%ebp) movl 44(%ebp), %eax movl %eax, -68(%ebp) movl $0, -32(%ebp) movl -48(%ebp), %eax movl %eax, -28(%ebp) movl -56(%ebp), %eax movl %eax, -24(%ebp) movl -64(%ebp), %eax movl %eax, -20(%ebp) movl -72(%ebp), %eax movl %eax, -16(%ebp) movl -16(%ebp), %eax movl %eax, 12(%esp) movl -20(%ebp), %eax movl %eax, 8(%esp) movl -24(%ebp), %eax movl %eax, 4(%esp) movl -28(%ebp), %eax movl %eax, (%esp) call foo movl %eax, -12(%ebp) movl -12(%ebp), %eax movl %eax, -32(%ebp) movl -32(%ebp), %eax leave ret
与仅生成的
-O1
相比Java_testJNI_foo: pushl %ebp movl %esp, %ebp subl $24, %esp movl 40(%ebp), %eax movl %eax, 12(%esp) movl 32(%ebp), %eax movl %eax, 8(%esp) movl 24(%ebp), %eax movl %eax, 4(%esp) movl 16(%ebp), %eax movl %eax, (%esp) call foo leave ret
-
使用
-O1
g++可以为生成更智能的代码%module test %{ int value() { return 100; } %} %feature("compactdefaultargs") foo; %inline %{ int foo(int a=value(), int b=value(), int c=value()) { return 0; } %}
简单的答案是完全禁用优化GCC会生成极其幼稚的代码-SWIG包装器和任何其他程序都是如此,如果不是更多地考虑到自动生成代码的风格的话。
- Python 3.7 和 excess_args 的 SWIG 问题
- 元组由 Swig 生成的 Python 包装器返回,用于C++向量
- 无法使用 SWIG 在 Python 中实例化C++类(获取属性错误)
- 从 C++ 到 Python 的 SWIG:未定义的符号导入问题
- 如何使用 swig C++命名空间作为 python 模块公开
- 分解SWIG Python接口 - 容器会产生命名空间冲突
- 如何制作一个满足SWIG中接口的python类
- 在python docker镜像上安装simstring(SWIG)
- SWIG c++到python:向量问题
- 如何使用 SWIG 接口访问 python 中的 C++ typedef'd 结构
- 方法 argv[] SWIG C++ / Python 中的错误,会发生什么?
- Swig/python : 什么时候需要 SWIG_init() ?
- python 和 swig 版本兼容性问题
- C++ 使用 SWIG 和 Visual Studio 2017 在 python 中导入 DLL
- Swig:在Python中使用c ++ STL复合体
- C++类在Python中使用SWIG的奇怪行为
- 使用 SWIG 绑定 Python/C++ 模板
- 在python swig中读取c ++ 2d数组
- Python swig包装的向量的向量的双显示为元组
- Python/SWIG类型错误