如何调整一些OpenMP 3.0的语句,使其可以在vs2010中使用?

How to adjust some OpenMP 3.0 statements so that they can be used in vs2010?

以下是一些 openmp 3.0 代码:

#pragma omp parallel
{
#pragma omp single nowait
{
    while(!texture_patches.empty())
    {
        int texture_size = calculate_texture_size(texture_patches, BORDER);
        mve::ByteImage::Ptr texture = mve::ByteImage::create(texture_size, texture_size, 3);
        mve::ByteImage::Ptr validity_mask = mve::ByteImage::create(texture_size, texture_size, 1);
        //...
        //the content of texture_patches changes here
        //...
        #pragma omp task
        dilate_valid_pixel(texture, validity_mask);//has no effects on the content of texture_patches
    }
    #pragma omp taskwait
    std::cout << "done. (Took: " << timer.get_elapsed_sec() << "s)" << std::endl;
}
}

众所周知,vs2010不支持openmp3.0。谁能告诉我如何调整上面的代码,以便它们可以在 vs2010 中使用?谢谢!

我不完全清楚 dilate_valid_pixel(texture, validity_mask) 如何影响 texture_patches 的内容,但 taskwait 位于 外部 的事实while 循环和缺少锁定 directives/calls 暗示 dilate_valid_pixel() 任务绝不会影响容器。在这种情况下,通常所做的是预填充工作项数组,然后使用并行循环处理该数组。代码如下:

// Create work items in serial

std::vector<*WorkItem> work_items;

while(!texture_patches.empty()){
    /* Try to insert each of the texture patches into the texture atlas. */
    for (std::list<TexturePatch>::iterator it = texture_patches.begin(); it != texture_patches.end();){
        TexturePatch texture_patch = *it;
        // ...
        if (bin.insert(&rect)){

            it = texture_patches.erase(it);//Attention!!! texture_patches changes
            remaining_patches--;
        } else {
            it++;
        }
    }
    //#pragma omp task
    //dilate_valid_pixel(texture, validity_mask);
    work_items.push_back(new WorkItem(texture, validity_mask));

    groups.push_back(group);
    material_lib.add_material(group.material_name, texture);
}

// Process the work items in parallel

#pragma omp parallel for
for (int i = 0; i < work_items.size(); i++)
    dilate_valid_pixel(work_items[i]->texture, work_items[i]->validity_mask);

std::cout << "done. (Took: " << timer.get_elapsed_sec() << "s)" << std::endl;

正在为未显示的工作项释放内存。原任务代码保留在评论中

一个重要的方面:如果 dilate_valid_pixel() 并不总是需要相同的时间来完成,那么将 schedule(dynamic,1) 子句添加到 parallel for 构造并使用块大小( 1) 以达到最佳性能。

这段代码并不完全等同于使用显式任务的代码,因为所有任务都是先创建然后执行的,而原始代码创建的任务与它们的执行并行,即上面的代码会执行得更差一点(如果任务创建非常快)比原始代码差很多(如果任务创建需要很长时间)。