Boost.python 和 OMP
Posted
技术标签:
【中文标题】Boost.python 和 OMP【英文标题】:Boost.python and OMP 【发布时间】:2015-03-10 15:48:15 【问题描述】:我无法弄清楚为什么使用 OMP 编译以下代码(chi2 距离)需要更长的时间。在此question 之后,我发布了 GIL,但仍然没有任何改进。
np::ndarray additive_chi2_kernel(const np::ndarray& _h0,
const np::ndarray& _h1)
auto dtype = np::dtype::get_builtin<float>();
auto h0 = _h0.astype(dtype);
auto h1 = _h1.astype(dtype);
enter code here
assert (h0.get_nd() == 2 && h1.get_nd() == 2);
float* ptr_h0 = reinterpret_cast<float*>(h0.get_data());
float* ptr_h1 = reinterpret_cast<float*>(h1.get_data());
int M0 = h0.shape(0);
int M1 = h1.shape(0);
int N = h1.shape(1);
float* result = new float[M0*M1]();
auto save_state = PyEval_SaveThread();
#pragma omp parallel
for(int m0 = 0; m0 < M0; ++m0)
for(int m1 = 0; m1 < M1; ++m1)
float error = 0;
for(int i = 0; i < N; ++i)
float sum = ptr_h0[m0*N+i] + ptr_h1[m1*N+i];
if (sum != 0)
float diff = ptr_h0[m0*N+i] - ptr_h1[m1*N+i];
error += (diff*diff/sum);
result[m0*M1+m1] = error;
PyEval_RestoreThread(save_state);
np::ndarray D = np::from_data(result,np::dtype::get_builtin<float>(),
py::make_tuple(M0,M1),py::make_tuple(sizeof(float)*M1,
sizeof(float)), py::object());
return D;
Boost 包装器是:
BOOST_PYTHON_MODULE(vgic)
// Initialize numpy
PyEval_InitThreads();
np::initialize();
py::def("additive_chi2_kernel",additive_chi2_kernel);
编译器标志:-std=c++11 -Wall -fopenmp -O3 -fPIC
所有线程都应该处于活动状态
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
20706 memecs 20 0 3980080 818004 42880 R 3179 0.6 7:34.04 python
但运行时间高于单核。对于 M0=100,M1=1000,N=1000 我得到
OMP: 2.214 seconds
SINGLE-CORE: 1.175 seconds.
可能的问题?
【问题讨论】:
【参考方案1】:您应该使用#pragma omp parallel for
在线程之间划分外循环。 #pragma omp parallel
只产生一组线程,但随后每个线程都在计算一切。
【讨论】:
当然。如此幼稚的错误:)我正在寻找一个完全不同的方向。以上是关于Boost.python 和 OMP的主要内容,如果未能解决你的问题,请参考以下文章
Boost::python 和 Eigen/dense 创建分段错误
提取和转换 boost::python::list 的列表元素