科学计算中的大多数人在共享内存并行化方面使用OpenMP作为准标准。
在pthreads上使用OpenMP是否有任何原因(可读性除外)?后者似乎更基本,我怀疑它可以更快更容易优化。
答案 0 :(得分:39)
它基本上归结为您希望对并行化的控制级别。如果您只想添加一些#pragma语句并快速拥有代码的并行版本,那么OpenMP非常棒。如果你想用MIMD编码或复杂的排队做一些非常有趣的事情,你仍然可以使用OpenMP完成所有这些工作,但在这种情况下使用线程可能要简单得多。 OpenMP在可移植性方面也有类似的优势,因为不同平台的许多编译器现在支持它,就像pthreads一样。
所以你绝对正确 - 如果你需要对并行化进行微调控制,请使用pthreads。如果要尽可能少地并行化,请使用OpenMP。
无论你决定去哪里,祝你好运!
答案 1 :(得分:22)
另一个原因:OpenMP是基于任务的,Pthreads是基于线程的。这意味着OpenMP将分配与核心数相同数量的线程。因此,您将获得可扩展的解决方案。使用原始线程来完成它并不是一件容易的事。
第二种观点:OpenMP提供了缩减功能:当您需要在线程中计算部分结果并将它们组合在一起时。您可以使用单行代码实现它。但是使用原始线程你应该做更多工作。
只要考虑一下您的要求并尝试理解:OpenMP足够适合您吗?你会节省很多时间。
答案 2 :(得分:8)
OpenMP需要一个支持它的编译器,并且使用pragma。这样做的好处是,在没有OpenMP支持的情况下进行编译时(例如,现在的PCC或Clang / LLVM),代码仍然可以编译。另外,请查看what Charles Leiserson wrote about DIY multithreading。
Pthreads是库的POSIX标准(IEEE POSIX 1003.1c),而OpenMP specifications将在编译器上实现;话虽如此,有各种pthread实现(例如OpenBSD rthreads,NPTL),以及许多支持OpenMP的编译器(例如带有-fopenmp标志的GCC,MSVC ++ 2008)。
Pthread仅在多个处理器可用时才有效并行,并且仅在代码针对可用处理器数量进行优化时才有效。因此,OpenMP代码更容易扩展。您可以将使用pthreads编译的代码与使用pthreads的代码混合在一起。
答案 3 :(得分:3)
你的问题类似于“我应该编程C还是汇编”这个问题,C是OpenMP,汇编是pthreads。
使用pthreads,您可以做更好的并行化,更好的意义非常紧密地调整到您的算法和硬件。这将是很多工作。
使用pthreads,生成一个不良并行化的代码也容易得多。
答案 4 :(得分:1)
迈克有点触及这个:在pthreads上使用OpenMP是否有任何原因(可读性除外)?
OpenMP在可移植性方面也有类似的优势,因为不同平台的许多编译器现在都支持它,就像pthreads一样
Crypto++是跨平台的,意味着在Windows,Linux,OS X和BSD上运行。它使用OpenMP在操作成本高昂的地方提供线程支持,例如模幂运算和模乘(以及可以执行并发操作的地方)。
Windows不支持pthread,但现代Windows编译器确实支持OpenMP。因此,如果您想要移植到非* nix,那么OpenMP通常是一个不错的选择。
正如迈克也指出的那样:
如果您只想添加一些#pragma语句并快速拥有代码的并行版本,那么OpenMP非常棒。
下面是一个使用Bernstein在RSA signatures and Rabin-Williams signatures...描述的使用Tweaked Roots在Rabin-Williams签名中使用的一些值来加密Crypto ++的例子:
void InvertibleRWFunction::Precompute(unsigned int /*unused*/)
{
ModularArithmetic modp(m_p), modq(m_q);
#pragma omp parallel sections
{
#pragma omp section
m_pre_2_9p = modp.Exponentiate(2, (9 * m_p - 11)/8);
#pragma omp section
m_pre_2_3q = modq.Exponentiate(2, (3 * m_q - 5)/8);
#pragma omp section
m_pre_q_p = modp.Exponentiate(m_q, m_p - 2);
}
}
符合迈克的观察 - 不需要细粒度控制和同步。并行化用于加速执行,源代码中的同步是免费的。
如果OpenMP 不 可用,则代码将缩减为:
m_pre_2_9p = modp.Exponentiate(2, (9 * m_p - 11)/8);
m_pre_2_3q = modq.Exponentiate(2, (3 * m_q - 5)/8);
m_pre_q_p = modp.Exponentiate(m_q, m_p - 2);
答案 5 :(得分:0)
当您需要并行执行相同的任务(即多个数据)时,OpenMP是理想的选择,这是一种SIMD机器(单指令多数据)。
当你想并行执行(完全不同的)任务时需要Pthreads,例如,在一个线程中读取数据并在另一个线程中与用户交互。
参见本页:
http://berenger.eu/blog/c-cpp-openmp-vs-pthread-openmp-or-posix-thread/