1

concurrency::parallel_for()在 Windows 应用程序(Visual Studio 2017)中使用循环划分一些工作。一切正常,但我担心锁定性能,所以我尝试了各种方法: std::mutex、windowsCRITICAL_SECTION等。

然后我尝试了concurrency::critical_section。该文档使它听起来应该更快,因为它知道并发运行时。

没有。它不仅速度不快,在某些情况下还非常危险。起初它只是炸毁了我的应用程序。在调试器中,我可以看到并发只是创建了无限线程。CRITICAL_SECTION当我将分区器从默认更改为静态分区器时,一切又开始工作了,但是一切都比使用 Windows甚至慢得多std::mutex

我想知道是否有人可以向我解释以下任何一个

  1. 为什么我concurrency::critical_section在我的 lambda(下)中使用默认分区器会使并发创建无限线程?
  2. 为什么(即使我通过使用 来让它工作static_partioner)比其他锁定机制parallel_for()慢得多?concurrency::critical_section
  3. 用例是concurrency::critical_section什么?

这是我的代码

#include <ppl.h>

void nonlinearReconstruction(const std::vector<Image>& window,
                             const Rect& rect,
                             Image& normals)
{
    concurrency::critical_section mtx;

    // This lambda uses the critical section "mtx" to control 
    // access to the shared image data in "normals".  Read pixels,
    // does math on them, and then sets other pixels.

    const auto op =
    [&normals, cols, rect, &window, &mtx] (int linearix)
    {
        // Determine what indices to use.
        const auto r = static_cast<int>(linearix / cols);
        const auto c = static_cast<int>(linearix % cols);
        const auto r0 = r + rect.top();
        const auto c0 = c + rect.left();
        const auto c1 = std::max(c + rect.left() - 1, 0);
        const auto r1 = r0; 
        const auto r2 = std::max(r + rect.top() - 1, 0);
        const auto c2 = c + rect.left();

        // Lock critical section to access shared memory pixels in "normals"

        mtx.lock();
        const auto ninit   = normals.getpel(r0, c0).asArray();
        const auto npx     = normals.getpel(r1, c1).asArray();
        const auto npy     = normals.getpel(r2, c2).asArray();
        mtx.unlock();  

        // Do heavy duty math on these pixels.  I've left out the code but 
        // no locking of any kind is done.  Just math on local data. 

        // ... blah blah blah


        // Lock again to set the corrected pixel in shared memory

        mtx.lock();
        normals.setpel(
            r + rect.top(), 
            c + rect.left(), 
            NormalVector(ntemp[0], ntemp[1], ntemp[2]));

        // Unlock one final time.

        mtx.unlock();
    };

    // Now call the parallel_for loop with the lambda above.
    // This version causes infinite thread creation
    concurrency::parallel_for(0, (int)totalix, op);

    // This version works but performs much slower with the 
    // concurrency::critical_section than with std::mutex or 
    // Windows CRITICAL_SECTION

    //  concurrency::parallel_for(0, (int)totalix, op, concurrency::static_partitioner());
}

我检查过的几件事:

  1. 我已经验证代码没有抛出任何异常。
  2. 此代码不是递归的。(我知道这concurrency::critical_section不是递归锁,但 std::mutex 也不是,而且工作得很好)。
  3. 我什至已经完成了它,并且我控制确实离开了例行程序。
4

0 回答 0