如何调整一些OpenMP 3.0语句,以便它们可以在vs2010中使用?

时间:2015-03-24 08:00:02

标签: visual-studio-2010 openmp

以下是一些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中使用?谢谢!

1 个答案:

答案 0 :(得分:0)

我并不完全清楚dilate_valid_pixel(texture, validity_mask)texture_patches的内容有何影响,但taskwait位于{{1>} 之外的事件while循环和缺少锁定指令/调用暗示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}})以获得最佳表现。

此代码与使用显式任务的代码并不完全等效,因为所有任务都是先创建然后执行,而原始代码与执行并行创建任务,即上面的代码执行起来会更糟(如果创建任务非常快(比如创建任务需要很长时间)比原始代码更糟糕。