【问题标题】:Boost.python and OMPBoost.python 和 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.

可能的问题?

【问题讨论】:

    标签: parallel-processing openmp boost-python


    【解决方案1】:

    您应该使用#pragma omp parallel for 在线程之间划分外循环。 #pragma omp parallel 只产生一组线程,但随后每个线程都在计算一切。

    【讨论】:

    • 当然。如此幼稚的错误:)我正在寻找一个完全不同的方向。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-20
    • 1970-01-01
    • 2021-03-22
    • 1970-01-01
    • 2010-11-29
    相关资源
    最近更新 更多