Parallel processing 单机上倍频程并行计算——软件包与实例

Parallel processing 单机上倍频程并行计算——软件包与实例,parallel-processing,octave,Parallel Processing,Octave,我想在一台机器上并行化一个八度的for循环(而不是集群)。我刚才问了一个关于八度音阶的平行版本的问题 答案是我下载了一个并行计算包,我确实下载了。该软件包似乎主要面向集群计算,但它确实提到了单机并行计算,但甚至不清楚如何运行并行循环 我还发现了关于这一点的另一个问题,但我没有找到一个在倍频程中并行循环的好答案: 有人知道我在哪里可以找到在倍频程中并行运行for循环的例子吗?倍频程循环非常慢,非常慢,最好用数组操作来表示。让我们以在2d域上计算简单的trig函数为例,如下所示(但计算点的数量要

我想在一台机器上并行化一个八度的for循环(而不是集群)。我刚才问了一个关于八度音阶的平行版本的问题

答案是我下载了一个并行计算包,我确实下载了。该软件包似乎主要面向集群计算,但它确实提到了单机并行计算,但甚至不清楚如何运行并行循环

我还发现了关于这一点的另一个问题,但我没有找到一个在倍频程中并行循环的好答案:


有人知道我在哪里可以找到在倍频程中并行运行for循环的例子吗?

倍频程循环非常慢,非常慢,最好用数组操作来表示。让我们以在2d域上计算简单的trig函数为例,如下所示(但计算点的数量要比打印点的数量更真实):

矢量化.m:

tic()
x = -2:0.01:2;
y = -2:0.01:2;
[xx,yy] = meshgrid(x,y);
z = sin(xx.^2-yy.^2);
toc()
将其转换为for循环将为我们提供 forloops.m:

tic()
x = -2:0.01:2;
y = -2:0.01:2;
z = zeros(401,401);
for i=1:401
    for j=1:401
        lx = x(i);
        ly = y(j);
        z(i,j) = sin(lx^2 - ly^2);
    endfor        
endfor
toc()
请注意,矢量化版本在更简单、更清晰的阅读方面已经“获胜”,但还有另一个重要的优势;时间安排截然不同:

$ octave --quiet vectorized.m 
Elapsed time is 0.02057 seconds.

$ octave --quiet forloops.m 
Elapsed time is 2.45772 seconds.
所以,如果您使用for循环,并且您具有完美的并行性,并且没有开销,那么您必须将其分解到119个处理器上,以实现与非for循环的平衡

别误会我的意思,并行性很好,但首先要让事情以串行方式高效工作


几乎所有octave的内置函数都已经矢量化了,因为它们在标量或整个数组上运行得同样好;因此,通常很容易将内容转换为数组操作,而不是逐个元素进行操作。对于那些不太容易的时候,你通常会看到已经存在的实用函数(比如meshgrid,它从2个向量的笛卡尔积生成2d网格)可以帮助你。

我正在计算大量RGB直方图。我需要使用显式循环来完成它。因此,计算每个直方图需要花费大量时间。因此,并行运行计算是有意义的。在八度音阶中,有一个由Jaroslav Hajek编写的(实验性)函数可以用来实现它

我的原始循环

histograms = zeros(size(files,2), bins^3);
  % calculate histogram for each image
  for c = 1 : size(files,2)
    I = imread(fullfile(dir, files{c}));
    h = myhistRGB(I, bins);
    histograms(c, :) = h(:); % change to 1D vector
  end
要使用parcellfun,我需要将循环体重构为一个单独的函数

function histogram = loadhistogramp(file)
  I = imread(fullfile('.', file));
  h = myhistRGB(I, 8);
  histogram = h(:); % change to 1D vector
end
那么我可以这样称呼它

histograms = parcellfun(8, @loadhistogramp, files);
我在我的电脑上做了一个小的基准测试。它是4个物理内核,启用了英特尔超线程

我的原始代码

tic(); histograms2 = loadhistograms('images.txt', 8); toc();
warning: your version of GraphicsMagick limits images to 8 bits per pixel
Elapsed time is 107.515 seconds.
非常有趣

octave:1> pkg load general; tic(); histograms = loadhistogramsp('images.txt', 8); toc();
parcellfun: 0/178 jobs donewarning: your version of GraphicsMagick limits images to 8 bits per pixel
warning: your version of GraphicsMagick limits images to 8 bits per pixel
warning: your version of GraphicsMagick limits images to 8 bits per pixel
warning: your version of GraphicsMagick limits images to 8 bits per pixel
warning: your version of GraphicsMagick limits images to 8 bits per pixel
warning: your version of GraphicsMagick limits images to 8 bits per pixel
warning: your version of GraphicsMagick limits images to 8 bits per pixel
warning: your version of GraphicsMagick limits images to 8 bits per pixel
parcellfun: 178/178 jobs done
Elapsed time is 29.02 seconds.
(并行和串行版本的结果相同(仅转置)


当我重复这几次时,运行时间几乎一直是一样的。并行版本运行大约30秒(+-2秒左右),同时包含4、8和16个子进程)

现在
pararrayfun
可以在那里找到使用示例:

如果Octave的这个特性(是一个特性吗?)没有很好的文档记录,这可能不是一个好主意。在这里,他们声称这是Octave的一个特性:但是,它似乎没有很好的文档记录。可能您正试图使用并行性来提高性能;如果是这样的话,你就不想使用串行或并行的循环,因为倍频程的循环(和IDL,以及在较小程度上的Matlab)是慢的。@JonathanDursi:我有两点意见。第一,我如何绕过for循环,比如在二维网格上计算函数f(x,y)?此外,即使八度循环中的for循环速度很慢,它们在并行化时可能会更快,因此仍然值得知道是否可以将八度循环中的for循环并行化。好的,我将不得不发布一些东西作为答案,因为它不适合评论:哇,这真的很令人惊讶……我对网格进行了很多改进,而且for循环真的非常慢(我想检查矢量化代码的运行时间如何随着网格的细化而扩展)…我想最好的方法是用C或Fortran语言编写并行代码进行大型仿真,或者只是矢量化倍频程/Matlab代码,但我认为前者可以快得多。还有一条评论:can Octave(或者Matlab)并行化你的vectorize.m程序?一个显而易见的问题:为什么octave(或者Matlab)“看不见”for循环只是在做一个数组运算,而且很快就完成了?在内部,这两个操作都可以简化为相同的机器代码指令。错误在于八度,而不是程序员,你不认为吗?@SanjayManohar编译器很难确定依赖项,并决定代码的哪些部分可以并行。使用矢量化操作使事情变得简单。现在,函数式语言允许开箱即用的并行性,但代价是适应一种完全不同的编程范式。因此,不,错不在Octave。先生,我读了一些关于Octave并行包的参考资料,但我仍然不明白为什么我们应该使用它函数前面的t“@”,你能解释一下吗?thx@affhendrawan根据SO规则,你应该为此发布一个新的SO问题。我不太记得Octave了,我上次在大学里用过它。幸运的是,这个问题已经存在于这个网站上了
octave:6> sum(sum((histograms'.-histograms2).^2))
ans = 0