OpenMP for 循环并行性问题
OpenMP for-loop parallelism issue
我是OpenMP的新手,我想将for循环迭代分成相等的块。到目前为止,我已经实现了:
#pragma omp parallel for schedule(static, 2) reduction(+:tot_ext)
for (int i = 0;i<num_pos;i++) {
if (fscanf(stdin,"%lu,%lun", &from, &to) != 2) {
fprintf(stderr, "Cannot read correctly intervals filen");
exit(1);
}
time = getTime();
text = (uchar*)malloc(to-from+2);
readlen = sdsl::extract(csa, from, to, text);
tot_time += (getTime() - time);
tot_ext += readlen;
if (Verbose) {
fwrite(&from,sizeof(ulong),1,stdout);
fwrite(&readlen,sizeof(ulong),1,stdout);
fwrite(text,sizeof(uchar),readlen, stdout);
}
free(text);
}
在一个内核上运行此查询所需的时间:2.72 秒。
在两个内核上运行此查询所需的时间:2.64 秒
我的问题是:为什么差异这么小?
OpenMP 设置一个线程池,在发生拆分时,根据情况在这些线程(部分(之间分配工作。
分配工作、启动工作线程并在最后将它们全部连接起来涉及大量成本。
除非在每次循环迭代中都有大量的工作要做,否则管理线程的开销成本可能远远超过好处 - 尝试并行化小循环比在单个处理器上运行它慢很多倍,这可以利用寄存器重用和本地核心缓存。
如果调用某些系统函数(如 fwrite(,它们也可能会强制线程之间同步,从而影响结果。
为了进行更公平的测试,请尝试使用以下工作块:
- 自给自足
- 不使用同步呼叫
- 本身就是实质性的作品
这将允许您以更适用的方式测试并行性的可能优势。
第一句话
引自 OpenMP 论坛 (http://forum.openmp.org/forum/viewtopic.php?f=3&t=764 (
通常,从多个线程读取和写入文件是 除非底层操作系统或 I/O 系统,否则这不是一个好主意 真正支持它(通常称为并行 I/O(。
很多时候 I/O 例程可用于同时从单独的文件读取/写入 时间。这是因为每个 I/O 实例都保留自己的数据区域。 告诉它正在从哪一行读取或写入。但是,当您 有多个线程尝试读取/写入您需要的同一文件 I/O 系统,用于为所有线程保留该文件的一个数据区域。 这不是通常的做法,因此您最终会序列化(或 以某种方式锁定(I/O。当然,这会减慢完成的过程和 因此,并行化 I/O 相对不切实际(因为您将 看不到加速(
这也适用于标准输出
因此,最好的情况fscanf
和fwrite
部分将是连续的,最坏的情况将是一团糟。
第二句话
如
• OpenMP 线程共享单个可执行文件、全局内存和堆 (马尔洛克,新(
因此,malloc 必须在omp critical
部分中(我不知道编译器是否自动执行此操作。
所以malloc
部分是顺序的。
最后备注:
tot_ext减少了,因此您不能期望在这里实现完全的可扩展性。
结论
最后,唯一真正并行处理的部分是readlen = sdsl::extract(csa, from, to, text);
如果它不是最昂贵的操作,您的时间是一致的。
仅关于性能,而不是线程安全 - 此测试的问题是您正在使用诸如stdin,getTime,malloc,fwrite,free等东西。这些函数中的大多数都是通过操作系统调用在内部实现的,从而导致不可预测的延迟和同步。尽量避免这样的电话,你会体验到更好的结果。
问题解决了。为什么我的测量时间不好的主要问题是因为使用了getTime((方法,该方法测量每个线程上花费的时间并将其总结。使用 omp_get_wtime((,我能够测量操作本身的时间。结果如下:
- 1 线程:2.72 秒
- 2 线程:1.41 秒
- 3 线程:0.94 秒
- 4 线程:0.73 秒
谢谢大家的回答。根据您的建议,我设法清理了一下我的代码,以便现在:)
- OpenMP for 循环并行性问题
- 如何在cython中使用并行性
- 如何在 Skylake 架构上最大化 sqrt-heavy loop 的指令级并行性?
- 在流水线执行中采用并行性
- C++17 在并行性方面究竟发生了哪些变化?(权威文档在哪里?
- OpenMP 按需嵌套并行性
- 通用 C++11 函数包装器,用于基于任务的并行性
- 将执行从一个线程移动到另一个线程,以实现任务并行性并在将来调用
- 互斥任务集的线程级并行性
- 使用TBB的并行性-我们的检查列表中应该包含哪些内容
- Xeon phi卸载模式如何利用线程并行性和矢量化
- 并行性与线程 - 性能
- 从基于线程的流水线转向基于任务的并行性?(C++)
- 编译包含动态并行性的代码失败
- std::async 使用相同的线程,我的代码没有实现并行性
- 内部和外部并行性
- 某些子网格未使用CUDA动态并行性执行
- 用STL算法替换for循环,同时允许并行性
- 使用boost::Thread的线程管理和并行性
- CUDA动态并行性:使用纹理内存时无效的全局写入