如何调整一些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
) 以达到最佳性能。
这段代码并不完全等同于使用显式任务的代码,因为所有任务都是先创建然后执行的,而原始代码创建的任务与它们的执行并行,即上面的代码会执行得更差一点(如果任务创建非常快)比原始代码差很多(如果任务创建需要很长时间)。
以下是一些 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
) 以达到最佳性能。
这段代码并不完全等同于使用显式任务的代码,因为所有任务都是先创建然后执行的,而原始代码创建的任务与它们的执行并行,即上面的代码会执行得更差一点(如果任务创建非常快)比原始代码差很多(如果任务创建需要很长时间)。