有一些关于这个问题的帖子,但没有一个满足我。 我没有openMp 3.0支持,我需要在地图上并行化迭代。我想知道这个解决方案是否有效:
auto element = myMap.begin();
#pragma omp parallel for shared(element)
for(int i = 0 ; i < myMap.size() ; ++i){
MyKeyObject * current_first = nullptr;
MyValueObject * current_second = nullptr;
#pragma omp critical
{
current_first = element->first;
current_second = element->second;
++element;
}
// Here I can use 'current' as in a usual loop
}
所以我使用for循环只是为了确保线程将处理相同数量的地图元素。这是正确的猜测还是会失败?
ps:我正在开发visual studio 2012,所以如果你有关于如何让我的编译器支持openMp 3.0的提示,这也可以解决我的问题..
答案 0 :(得分:9)
这不是您问题的直接答案,但我会尝试为您节省一些未来糟糕的“OpenMP with Visual Studio”体验。
Microsoft C / C ++编译器仅支持OpenMP 2.0。由于OpenMP内置于编译器内核并且不是附加软件包(除非有人提出外部源到源转换引擎),并且微软似乎不是,所以无法使其支持OpenMP 3.0或更高版本。有兴趣在推动自己的解决方案的同时提供进一步的OpenMP支持(见下文)。因此,您应该获得与Visual Studio集成的英特尔C / C ++编译器或者像GCC或PGI C / C ++编译器这样的独立编译器。
如果您是专门针对Windows开发的,那么您可能希望放弃OpenMP并使用Concurrency Runtime,特别是PPL。 PPL附带Visual Studio 2012及更新版本,并为STL中的某些算法提供数据和任务并行等效项。您感兴趣的是concurrency::parallel_for_each()
,它是std::for_each()
的并行版本。它适用于前向迭代器,虽然不如随机迭代器那样有效。但是你必须确保处理地图的一个元素需要至少一千条指令,否则并行化将不会有益。
如果您的目标是跨平台兼容性,那么Intel Threading Building Blocks(简称英特尔TBB)是PPL的替代方案。它提供tbb::parallel_do()
算法,该算法专门用于处理前向迭代器。关于每个地图元素的工作量的相同警告适用。
答案 1 :(得分:2)
您的方法将起作用,因为您在关键部分中访问并迭代共享对象@row.Date.ToString("dd-MM-yyyy")
。无论这不是对性能有益,你都必须进行测试。这是您可能想要考虑的替代方法。我称之为“快进”方法。
我们假设你想并行执行此操作
element
您可以使用OpenMP 2.0
执行此操作for(auto element = myMap.begin(); element !=myMap.end(); ++element) {
foo(element->first, element->second);
}
每个线程都运行#pragma omp parallel
{
size_t cnt = 0;
int ithread = omp_get_thread_num();
int nthreads = omp_get_num_threads();
for(auto element = myMap.begin(); element !=myMap.end(); ++element, cnt++) {
if(cnt%nthreads != ithread) continue;
foo(element->first, element->second);
}
}
个迭代器。但是,每个帖子只会调用myMap.size()
foo
。您的方法只运行myMap.size()/num_threads
迭代器。但是,它需要在每次迭代时使用临界区。
只要通过nthreads迭代器“快进”的时间远小于myMap.size()/num_threads
的时间,快进方法就是有效的,即:
foo
但是,如果nthreads*time(++elements) << time(foo)
的时间是有序的,那么迭代的时间和foo
正在读/写内存,那么foo
可能是内存带宽限制的,并且不会随着无论如何,线程的数量。
答案 2 :(得分:0)
你的方法不起作用 - 因为概念问题和一些错误的混合。
没有简单的方法来使用迭代器并行化对地图的访问,因为map迭代器不是随机访问。您可能希望手动拆分密钥,然后在不同的线程上使用密钥集的不同部分。