pybind11 以某种方式减慢了 c++ 函数
Posted
技术标签:
【中文标题】pybind11 以某种方式减慢了 c++ 函数【英文标题】:pybind11 somehow slows c++ function 【发布时间】:2020-11-18 12:26:34 【问题描述】:我看到的所有 ***/github 问题都是关于在编组对象的情况下加速 Python 的函数调用。 但我的问题是关于pybind11 C++模块函数中纯c++函数的工作时间。
我有从本地 C++ 库类加载数据集和调用 train 方法的训练函数:
void runSvm()
// read smvlight file into required sparse representation
auto problem = read_problem( "random4000x20.train.svml" );
CSvmBinaryClassifierBuilder::CParams params( CSvmKernel::KT_Linear );
params.Degree = 3;
params.Gamma = 1/20;
params.Coeff0 = 0;
// measure time here
using namespace std::chrono;
system_clock::time_point startTime = high_resolution_clock::now();
CSvmBinaryClassifierBuilder( params ).Train( *problem ); // measure time only for this line
nanoseconds delay = duration_cast<nanoseconds>( high_resolution_clock::now() - startTime );
std::cout << setprecision(3) << delay / 1e6 << std::endl;
我通过 pybind11 将此函数绑定到 Python:
PYBIND11_MODULE(PythonWrapper, m)
m.def( "runSvm", &runSvm );
然后编译pybind11模块库并从Python中调用它。定时器值超过 3000ms。 但是当我从纯 C++ 调用这个函数时,定时器的值大约是 800 毫秒。 当然,我期待一些开销,但不是在这个地方,也不是那么多。
我在一个线程中运行它,两种情况下它都 100% 加载了一个内核。
问题可能出在哪里?谁面临同样的问题,您是如何处理的?
【问题讨论】:
这是可重复的吗?可能因为文件在缓存中,C++ 版本运行得更快。您真的在比较两个等效程序吗?例如:它们是用相同的编译器和相同的代码优化设置编译的吗? 是的,测试程序和这个描述一样简单,我有一个本地发布版本的库,我从中调用 Train()。相同的二进制文件用于链接 c++ 测试样本或 pybind11 模块。 (不确定来自 pybind11 的编译标志,但这不太可能是问题) 除非有证据证明不是这样,否则我假设 pybind11 库没有经过优化编译。 @Botje,我检查了 CMakeFiles 目录,它是用 CXX_FLAGS = -O3 -DNDEBUG -fPIC -fvisibility=hidden -flto -fno-fat-lto-objects -fopenmp 编译的我>。除了 -flto -fno-fat-lto-objects 之外,C++sample 使用相同的标志编译 pybind11 不能减慢它调用的函数。减速必须是其他原因造成的。如果没有看到minimal reproducible example,真的很难猜出它可能是什么。 【参考方案1】:当我处理一个可重现的示例时,我发现我在 C++ 示例(它基于 libsvm 参数证明为“rbf”)和 pybind11 lib(它是硬编码的“线性”)中比较了不同的 svm 内核。修复它并比较相同的算法后,时间没有差异。
【讨论】:
以上是关于pybind11 以某种方式减慢了 c++ 函数的主要内容,如果未能解决你的问题,请参考以下文章
如何使用 pybind11 在 C++ 线程中调用 Python 函数作为回调