什么是最快的并行化代码方法?

3
我是一位有用的助手,可以为您翻译文本。
我有一个图像处理程序,我认为可以很快地实现并行化。每个像素需要大约2k次操作,这些操作不依赖于相邻像素的操作,因此将工作分割成不同的单元相当简单。
我的问题是,最好的方法是什么,这样我就可以获得最快的速度提升效果?
理想情况下,我正在寻找的库/方法应满足以下标准:
  1. 在未来5年仍然存在。类似CUDA或ATI的变体可能会被不太依赖硬件的解决方案所取代,因此我希望选择更加稳定的方案。如果我的CUDA印象是错误的,我欢迎纠正。
  2. 实现速度要快。我已经编写了这段代码并且它可以串行运行,但非常缓慢。理想情况下,我只需重新编译我的代码以实现并行化,但我认为这可能是一种幻想。如果我使用不同的范例(例如着色器)重写它,那也可以。
  3. 不需要太多硬件知识。我希望能够不必指定线程数或操作单元,而是根据使用的机器自动计算出所有这些内容。
  4. 可在廉价硬件上运行。这可能意味着需要150美元的显卡或其他设备。
  5. 可在Windows上运行。类似GCD的东西可能是正确的选择,但我所针对的客户群体不会很快转向Mac或Linux。请注意,这使得问题的回答与this other question有所不同。

我应该关注哪些库/方法/语言?我已经看过OpenMP、CUDA、GCD等等,但我想知道是否还有其他的东西我错过了。

我现在倾向于像着色器和opengl 2.0这样的东西,但可能不是正确的选择,因为我不确定我能以这种方式获得多少内存访问--这些2k操作需要以很多方式访问所有相邻的像素。

5个回答

1

最简单的方法可能是将您的图片分成可以并行处理的部分(4、8、16,取决于核心数)。然后为每个部分运行不同的进程。

就具体操作而言,请看看OpenCL。它希望能够长期存在,因为它不是特定于供应商的,并且NVidia和ATI都希望支持它。

一般来说,由于您不需要共享太多数据,所以这个过程非常简单明了。


我会看一下。OpenCL需要我指定核心数量吗?我希望只是将所有东西分成“工作单元”并让它自己处理。 - mmr
好的,只需开发您的算法,使其能够与任意数量的核心配合使用。 - CookieOfFortune

1

我还建议使用Threading Building Blocks。我们在我工作的公司中将其与Intel® Integrated Performance Primitives一起用于图像分析。

Threading Building Blocks(TBB)类似于OpenMP和Cilk。它使用OpenMP进行多线程处理,只是包装在更简单的接口中。使用它时,您不必担心要创建多少个线程,只需定义任务即可。如果可能,它会分割任务以保持所有内容繁忙,并为您执行负载平衡。

Intel集成性能原语(Ipp)具有针对视觉的优化库。其中大部分都是多线程的。对于我们需要但IPP中没有的功能,我们使用TBB进行线程处理。

使用这些工具,当我们使用IPP方法创建图像时,我们可以获得最佳结果。它会填充每行,使得任何给定的缓存行完全包含在一行中。然后,我们不会将图像中的一行分配给多个线程。这样,我们就不会出现两个线程尝试写入同一缓存行的虚假共享问题。


我熟悉IPP,但发现多线程/平铺代码对我来说不太有用(我的图像都是ushorts,而不是uint8)。如果TBB解决了这个问题,那就非常令人兴奋... - mmr
我们使用既包含 ushorts 也包含 uint8 的图像。TBB 可以与两者一起使用。事实上,我们编写的大多数函数都是接受这两种类型并使用 TBB 的模板。 - Ed_S
澄清一下,IPP有不同类型的内存分配器。这些分配器确保每个缓存行完全包含在一行中。它们通过填充每行的末尾来实现这一点,以使缓存行充满。这会浪费一点内存,但在1025宽×1024高的图像上仅为3%。这是最坏的情况。通常情况下,您将浪费更少的内存。 - Ed_S

0

我还没有,我会去查看一下。 - mmr

0

我没有使用过它,但可以看看Cilk。他们团队中的大佬之一是Charles E. Leiserson;他是CLRS的“L”,这是全球最广泛/受尊敬的算法书。

从我的简短阅读来看,你只需要“标记”你现有的代码,然后通过他们的编译器运行它,编译器将自动/无缝地并行化代码。这是他们的卖点,所以你不需要像其他选项(如OpenMP)那样从头开始考虑并行性。


0

如果您已经有一个在C、C++或Fortran中工作的串行代码,那么您应该认真考虑OpenMP。与许多其他并行化库/语言/系统/等相比,它的一个重要优点是您可以一次并行化一个循环,这意味着您可以获得有用的加速而无需重新编写或更糟糕的是重新设计程序。

就您的要求而言:

  1. OpenMP在高性能计算中被广泛使用,有很多“权威”支持和积极的开发社区--www.openmp.org。

  2. 如果您足够幸运选择了C、C++或Fortran,则实现速度足够快。

  3. OpenMP实现了共享内存的并行计算方法,因此在“不需要理解硬件”的论点中具有很大的优势。您可以让程序在运行时自动确定它有多少个处理器,然后将计算分布到所有可用的处理器上,这是另一个优点。

  4. 在您已经拥有的硬件上运行,无需昂贵或廉价的额外图形卡。

  5. 是的,有适用于Windows系统的实现。

当然,如果你一开始没有明智地选择C、C++或Fortran,那么很多建议只有在你将其重写为其中一种语言后才适用!

祝好

马克


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接