我使用OpenMP和Intel TBB进行了并行化图像卷积和lu分解。我在1-8核心上测试它。但是,当我通过分别使用set_num_threads(1)和task_scheduler_init InitTBB(1)指定一个线程时,在OPenMP和TBB中的1个核心上尝试它;由于TBB开销,TBB性能与顺序代码相比显示出一些小的降级,但令人惊讶的是OpenMP没有显示单核上的任何开销,并且执行与顺序代码完全相同(使用Intel O3优化级别)。我正在使用OpenMP循环的静态调度。这是现实还是我做错了?
答案 0 :(得分:2)
如果只使用一个线程运行OpenMP运行时,它可能不会创建任何线程。
此外,仅使用OpenMP并行化指令有时也会使串行代码运行得更快,因为您实际上是在为编译器提供更多信息。例如,工作共享构造告诉编译器循环的迭代是彼此独立的,它可能无法自己推断,并且允许编译器使用更积极的优化策略。当然,并非总是如此,但我已经看到它发生在“真实世界代码”中。
答案 1 :(得分:0)
OpenMP是编译器完成所有工作的地方。如果编译器知道它将是串行代码,那么它可以完全合法地跳过所有并行位。
据我所知,TBB基本上只是一个图书馆。总是必须让你的算法用必要的部分装饰,以便并行和串行运行它。
答案 2 :(得分:0)
OpenMP将代码的装饰部分(#pragma omg for / parallel)分配到主线程(也可以在没有OpenMP的情况下执行)和其他线程。
如果配置为仅使用1个线程,那么这只是主线程,执行时没有OpenMP指令。没有开销,导致执行路径没有分叉。
答案 3 :(得分:0)
关于OpenMP的事情是编译器为你工作,它需要对顺序代码进行最少的修改,并且如果给每个线程的任务非常大,通常会给出一些好的结果。我建议尝试使用Pthread或c ++ 11上的线程测试您的代码并查看结果。