我使用 OpenMP 的线程越多,执行时间就越长,这是怎么回事?



我写了一个程序,它接受字典并找到字典中所有回文的单词。我试图并行化此字典的遍历,以及使用 OpenMP 检查单词是否为回文的逻辑的执行。但是,当我注意到执行时间随着我允许程序利用越来越多的线程而增加时。对此有何解释?我的代码中是否有错误?

#pragma omp parallel    //block of code that we want to execute using multiple threads
#pragma omp single  //we only want one thread to iterate through the foor loop and spawn tasks for the other threads
{
#pragma omp task untied     /* iterating through the for loop is the main task, so 
* burden should be shared if execution is suspended
*/
{
for (set<string>::iterator i = wordList.begin(); i != wordList.end(); ++i){
#pragma omp task    //spawn the tasks of evaluating whether each word should be inserted into palindrome list
{
if (isPalindrome(*i)){  //if the word is by itself a palindrome, insert
palindromes.insert(*i);
}
/* if the reverse of the current word is in the wordlist and it hasn't already been inserted,
* insert them both into set of palindromes
*/ 
else if (wordList.find(reverseWord(*i)) != wordList.end()){
if(palindromes.find(*i) == palindromes.end()){
palindromes.insert(*i);
palindromes.insert(reverseWord(*i));
}
}
}
}
}
}

我使用对 omp_set_num_threads(Argv[1]( 的调用来更改运行时允许的最大线程数。我正在超级计算机上执行此程序,因此我认为这不是计算机"过载"之类的问题。什么给?我是否误解了如何使用 OpenMP?我在此代码块之前和之后使用 omp_get_wtime(( 的两个调用来测量执行时间。

编辑:回文和wordList都是std::set,isPalindrome通过指针操作检查单词是否是回文,reverseWord返回单词的反转字符(对于此任务,回文也是一个单词,在单词列表中找到反向,例如。

每个任务执行的计算量(CPU 周期(是否弥补了生成它们所做的工作?

我可能会建议在这里的任务中使用#pragma omp parallel for,因为在整个操作过程中您的单词集具有固定的大小。然而,问题在于将单词插入palindromes列表时的关键会话。

根据(当前(缺失代码的描述,问题是您反复创建新的string对象以传递给isPalindrome和其他地方。 每个字符串副本都将导致内存分配(以及随后的空闲(,并且标准内存分配器不可重入,并且如果当前正在分配一个线程,则会阻塞另一个线程。

一种部分解决方案是将参数作为const std::string &传递给isPalindrome,这将避免复制。 在这方面reverseWord会更成问题,因为它需要返回修改后的字符串,但该参数仍然可以通过引用传递。

相关内容

最新更新