2012-05-09 5 views
9

Я хотел бы распараллелить цикл for в Octave на одной машине (в отличие от кластера). Я задал вопрос о параллельной версии Octave некоторое время назад parallel computing in octaveПараллельные вычисления в Octave на одной машине - пакет и пример

И ответ предложил мне загрузить пакет параллельных вычислений, который я сделал. Пакет, похоже, в значительной степени ориентирован на кластерные вычисления, но он упомянул о параллельных вычислениях на одной машине, но не был ясен, как запускать даже параллельный цикл.

Я также нашел другой вопрос о SO об этом, но я не нашел хороший ответ для распараллеливания циклов в октаве: Running portions of a loop in parallel with Octave?

Кто-нибудь знает, где я могу найти пример запуска для цикла параллельно в Октаве ???

+0

Если эта функция (особенность) октавных ISN? «Хорошо документировано, это может быть не такая хорошая идея. –

+0

Здесь они утверждают, что это особенность Octave: http://octave.sourceforge.net/parallel/ Но, похоже, это не хорошо документировано. – db1234

+0

Предположительно вы пытаетесь использовать параллельность для повышения производительности; если это так, вы не хотите использовать для циклов в последовательном * или * параллельно, так как для циклов в Octave (а IDL и, в меньшей степени, Matlab) медленный медленный медленный. –

ответ

10

Октавные петли медленные, медленные, медленные, и вам намного лучше выражать вещи в терминах массивных операций. Давайте рассмотрим пример оценки функции простого Триг над 2d области, так как в этом 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() 

Преобразования его для петель дает нам 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. 

Так что, если вы используете для петель, и вы имели совершенный параллелизм без дополнительных затрат, вы должны разорвать этот вверх на 119 процессоров просто сломать даже с не-для -Лоп!

Не поймите меня неправильно, параллелизм велик, но сначала получите эффективную работу в серийном режиме.

Почти все встроенные функции октавы уже векторизованы в том смысле, что они одинаково хорошо работают на скалярах или целых массивах; поэтому часто бывает проще преобразовать объекты в операции массива, а не выполнять элементы по элементам. В те времена, когда это не так просто, вы, как правило, видите, что есть полезные функции (такие как meshgrid, который генерирует 2d-сетку из декартова продукта из двух векторов), которые уже существуют, чтобы помочь вам.

+0

Вау, это действительно удивительно ... Я много рафинировал сетку, и цикл for действительно невероятно медленный (я хотел проверить, как время работы векторизованного кода масштабируется с уточнением сетки) ... Я думаю, лучше всего, может быть, сделать параллельный код в C или Fortran для больших симуляций или просто векторизовать код Octave/Matlab , но я думаю, что первое может быть намного быстрее. – db1234

+0

Еще один комментарий: может ли Octave (или Matlab) распараллелить что-то вроде вашей программы vectorize.m? – db1234

+0

Очевидный вопрос: почему не может быть октава (или matlab) ** «видеть» **, что цикл for просто выполняет массив op и делает это быстро? Внутри, оба из них могут быть упрощены к тем же инструкциям машинного кода. Ошибка в октаве, а не в программисте, вы не думаете? –

11

Я вычисляю большое количество гистограмм RGB. Мне нужно использовать явные петли для этого. Поэтому вычисление каждой гистограммы занимает заметное время. По этой причине использование параллельных вычислений имеет смысл. В Октаве есть (экспериментальная) функция 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 

Когда я повторил это несколько раз, время работы было почти одинаковым все время. Параллельная версия была runni нг около 30 секунд (+ - приблизительно 2с) с обоими 4, 8, а также 16 подпроцессов)

+0

Сэр, я прочитал несколько ссылок о параллельном пакете октавы, но я до сих пор не понимаю, почему мы должны поставить «@» перед функцией. Вы можете это объяснить? thx – affhendrawan

+0

@affhendrawan Вы должны опубликовать новый вопрос SO для этого, согласно правилам SO. Я не очень хорошо помню Октава, я в последний раз использовал его в колледже. К счастью для вас, вопрос уже существует на этом сайте http://stackoverflow.com/questions/25355028/what-is-the-purpose-of-the-symbol-in-front-of-a-variable-in-octave – user7610