在单个机器上的Octave中并行计算 - 包和示例

时间:2012-05-09 16:46:00

标签: parallel-processing octave

我想在一台机器上(而不是集群)并行化Octave中的for循环。我刚才问了一个关于Octave的并行版本的问题 parallel computing in octave

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

我还发现了另外一个关于此问题的问题,但我找不到在Octave中并行化循环的好答案: Running portions of a loop in parallel with Octave?

有谁知道我在哪里可以找到在Octave中并行运行for循环的例子

3 个答案:

答案 0 :(得分:12)

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

我原来的循环

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个物理内核,启用了Intel HyperThreading。

我的原始代码

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.

使用parcellfun

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.

(并行和串行版本的结果相同(仅转置)。

octave:6> sum(sum((histograms'.-histograms2).^2))
ans = 0

当我多次重复这个时,运行时间几乎都是一样的。并行版本运行大约30秒(+ - 约2s),包括4个,8个和16个子过程)

答案 1 :(得分:10)

Octave循环缓慢,缓慢,缓慢,你在表达数组操作方面做得更好。让我们举一个例子来评估2d域上的一个简单的trig函数,就像在这个3d octave graphics example中一样(但是计算的点数更加真实,而不是绘图):

vectorized.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个处理器,以便在非循环中实现收支平衡!

不要误会我的意思,并行性很好,但首先要让事情有效地串联起来。

几乎所有八度音程的内置函数都已经过矢量化,因为它们在标量或整个数组上运行得相同;因此,将事物转换为数组操作通常很容易,而不是逐个元素地执行操作。对于那些不那么容易的时候,你通常会看到有一些实用函数(比如meshgrid,它从2个向量的笛卡尔积中生成一个二维网格)已经存在以帮助你。

答案 2 :(得分:4)

现在可以在那里找到pararrayfun用法示例: http://wiki.octave.org/Parallel_package