我正在Linux中创建一个多线程应用程序。 场景如下:
假设我有一个类BloomFilter
的 x 实例,并且我有一些 y GB 的数据(大于可用内存)。我需要在每个布隆过滤器实例中测试这 y GB 数据的成员资格。很明显,并行编程将有助于加快任务速度,因为我只读取数据,因此可以在所有进程或线程之间共享数据。
现在我对使用Cilk,Cilk ++或OpenMP哪个(哪个更好)感到困惑。我也对多线程或多处理哪一个感到困惑
Plus 是英特尔对 Cilk 的当前实现。它们都是多线程环境,即在执行过程中生成多个线程。
如果您不熟悉并行编程,OpenMP 可能更适合您,因为它允许对已经开发的顺序代码进行更容易的并行化。您是否已经有代码的顺序版本?
OpenMP 使用杂注来指示编译器哪些部分代码必须并行运行。如果我正确理解您的问题,您可能需要这样的东西:
#pragma omp parallel for firstprivate(array_of_bloom_filters)
for i in DATA:
check(i,array_of_bloom_filters);
不同布隆过滤器的实例在每个线程中复制,以避免在线程之间共享数据时发生争用。
更新:本文实际上考虑了一个非常不平衡的应用程序,即不同的 taks(在不同的线程上分配)可能会产生非常不同的工作负载。引用您提到的论文"挑战调度的高度不平衡的任务图,负载平衡、终止检测和任务粗略策略"。考虑到为了平衡线程之间的计算,有必要减小任务大小,从而增加同步所花费的时间。换句话说,良好的负载平衡总是有代价的。 对你的问题的描述不是很详细,但在我看来,你的问题相当平衡。如果不是这种情况,那就去 Cilk,它的工作窃取方法可能是不平衡工作负载的最佳解决方案。
在这篇文章发布时,英特尔正在投入大量精力来提升Cilk(tm) Plus;最近,一些精力已经转移到OpenMP 4.0上。一般来说,很难将OpenMP与Cilk(tm)Plus进行对比。
如果无法在线程之间均匀分配工作,则可以在 OpenMP 版本中设置 schedule(运行时),然后在运行时尝试环境变量的各种值,例如 OMP_SCHEDULE=引导、OMP_SCHEDULE=动态、2 或 OMP_SCHEDULE=auto。这些是最接近OpenMP的类比,类似于Cilk(tm)Plus的工作窃取工作方式。英特尔 MKL 库中的一些稀疏矩阵函数实际上会首先扫描作业,并确定要分配给每个线程的数量,以平衡工作。要使此方法有用,串行扫描和分配所花费的时间必须低于并行工作所花费的时间。工作窃取或动态调度可能会失去 OpenMP 在通过固定具有缓存局部性的线程(例如通过 OMP_PROC_BIND=close)来提升缓存局部性方面的许多潜在优势。糟糕的缓存局部性在 NUMA 体系结构上成为一个更大的问题,它可能会导致在远程内存访问上花费大量时间。OpenMP 和 Cilk(tm) Plus 都具有在串行和并行执行之间切换的功能。