Вопрос по vectorization, matlab, parallel-processing, octave – Векторизация для сетки в Matlab (или Octave)

5

Векторизованный код в Matlab выполняется намного быстрее, чем цикл for (см.Параллельные вычисления в Octave на одной машине - пакет и пример для конкретных результатов в октаве)

С учетом сказанного, есть ли способ векторизовать код, показанный далее в Matlab или Octave?

<code>x = -2:0.01:2;
y = -2:0.01:2;
[xx,yy] = meshgrid(x,y);
z = sin(xx.^2-yy.^2);
</code>
Проверьте только что добавленныйbsxfun реализация, которая также говорит об использовании GPUhere Divakar

Ваш Ответ

3   ответа
5
Vectorization for meshgrid and ndgrid

Если вы все еще заинтересованы в нахождении векторизованной реализации, чтобы сделатьmeshgrid на основе кода в проблеме быстрее, позвольте мне предложить векторизованный метод сbsxfun и это портированная версия GPU. Я твердо верю, что люди должны смотреть вvectorization with GPUs как многообещающий вариант для ускоренияMATLAB коды. Коды, которые используютmeshgrid или жеndgrid и чьи выходы должны работать с какой-то поэлементной настройкой работы, идеальной почвой для использованияbsxfun в эти коды. Чтобы добавить к этому, использование графического процессора сbsxfunЭто позволяет ему работать независимо от сотен и тысяч доступных ядер CUDA, что делает его просто идеальным для реализации на GPU.

Для вашей конкретной проблемы входные данные были -

x = -2:0.01:2;
y = -2:0.01:2;

Далее у вас было -

[xx,yy] = meshgrid(x,y);
z = sin(xx.^2-yy.^2);

Сbsxfunэто становится одной строкой -

z = sin(bsxfun(@minus,x.^2,y.^2.'));
Benchmarking

Советы по тестированию GPU были взяты изИзмерение и улучшение производительности графического процессора.

%// Warm up GPU call with insignificant small scalar inputs
temp1 = sin_sqdiff_vect2(0,0);

N_arr = [50 100 200 500 1000 2000 3000]; %// array elements for N (datasize)
timeall = zeros(3,numel(N_arr));

for k = 1:numel(N_arr)
    N = N_arr(k);
    x = linspace(-20,20,N);
    y = linspace(-20,20,N);

    f = @() sin_sqdiff_org(x,y);%// Original CPU code
    timeall(1,k) = timeit(f);
    clear f

    f = @() sin_sqdiff_vect1(x,y);%// Vectorized CPU code
    timeall(2,k) = timeit(f);
    clear f

    f = @() sin_sqdiff_vect2(x,y);%// Vectorized GPU(GTX 750Ti) code
    timeall(3,k) = gputimeit(f);
    clear f
end

%// Display benchmark results
figure,hold on, grid on
plot(N_arr,timeall(1,:),'-b.')
plot(N_arr,timeall(2,:),'-ro')
plot(N_arr,timeall(3,:),'-kx')
legend('Original CPU','Vectorized CPU','Vectorized GPU (GTX 750 Ti)')
xlabel('Datasize (N) ->'),ylabel('Time(sec) ->')

Associated functions

%// Original code
function z = sin_sqdiff_org(x,y)
[xx,yy] = meshgrid(x,y);
z = sin(xx.^2-yy.^2);
return;

%// Vectorized CPU code
function z = sin_sqdiff_vect1(x,y)
z = sin(bsxfun(@minus,x.^2,y.^2.')); %//'
return;

%// Vectorized GPU code
function z = sin_sqdiff_vect2(x,y)
gx = gpuArray(x);
gy = gpuArray(y);
gz = sin(bsxfun(@minus,gx.^2,gy.^2.')); %//'
z =  gather(gz);
return;
Results

enter image description here

Conclusions

Как показывают результаты, векторизованный метод с графическим процессором показывает хорошее улучшение производительности, что составляет около4.3x против векторизованного кода процессора и6x против оригинального кода. Пожалуйста, имейте в виду, что GPU должен преодолевать минимальные накладные расходы, которые требуются при его настройке, поэтому, чтобы увидеть улучшение, необходим по меньшей мере приличный вход Надеюсь, люди будут исследовать большеvectorization with GPUsКак нельзя было подчеркнуть достаточно!

6

Как отмечает @Jonas, в MATLAB доступно несколько опций, и то, что работает лучше всего, зависит от нескольких факторов, таких как:

How large is your problem How many machines you have available Do you have a GPU Does MATLAB already multithread the operations

Многие поэлементные операции теперь являются многопоточными в MATLAB, и в этом случае использование PARFOR, как правило, не имеет смысла (если у вас нет нескольких машин и лицензий MATLAB Distributed Computing Server).

Действительно огромные проблемы, требующие памяти нескольких машин, могут быть полезныраспределенные массивы.

Использование графического процессора может превзойти многопотоковую производительность одной машины, если ваша проблема имеет подходящий размер и тип для вычислений на графическом процессоре. Векторизованный код, как правило, наиболее подходит для распараллеливания через графический процессор. Например, вы можете написать свой код, используяgpuArrays из Parallel Computing Toolbox, как это и так, чтобы все работало на GPU.

x = parallel.gpu.GPUArray.colon(-2,0.01,2);
y = x;
[xx,yy] = meshgrid(x,y); % xx and yy are on the GPU
z = arrayfun( @(u, v) sin(u.*u-v.*v), xx, yy );

Я преобразовал последнюю строку там вarrayfun вызов как более эффективный при использованииgpuArrays.

Большой! Вы правы в том, что Matlab автоматически выполняет многопоточность вычислений, которые я дал выше. Я выполнял вычисления из дома без Parallel Computing Toolbox, и только сейчас я запустил их на компьютере с инструментарием, и это было сделано параллельно. И спасибо за пример с графическим процессором ... Я никогда не использовал графический процессор, но подозреваю, что он пригодится в будущем, и полезно знать, что код кажется простым. db1234
Хотя это старый пост, я смог реализовать его с помощью bsxfun на GPU и получил хорошие ускорения. Размещено решение здесь же!
5

В Matlab единственный способ получить встроенные векторизованные функции для многопоточности - это дождаться, пока MathWorksреализовать их в качестве таких.

Кроме того, вы можете записать векторизованные вычисления в виде цикла и запустить их параллельно, используяparfor.

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

for Циклы в Matlab, как правило, медленнее, чем векторизованные вычисления. Таким образом, идеальная ситуация для оптимальной производительности - попытаться распараллелить векторизованный код, если это возможно. db1234
Я смог получить действительно хорошее ускорение сbsxfunпо внедрению графического процессора и опубликовал решение с нимhere
@dblazevski: Если вы хотите использовать графический процессор от Matlab, посмотрите документацию Parallel Computing Toolbox. В противном случае посмотрите документацию CUDA и их примеры.
Правда. Я проверил пример, приведенный вstackoverflow.com/questions/10520495/… Я даже много улучшил сетку. В Matlabfor Цикл был медленнее, но только в 5 раз больше, чем векторизованная версия. В Октавеfor Код цикла взялmuch дольше (как в 100 раз дольше ...). Я уже некоторое время интересовался графическими процессорами, хотя и не давал им попробовать ... Знаете ли вы отправную точку, чтобы научиться использовать / программировать графический процессор? db1234
@dblazevski:parfor помогает, но вы можете посмотреть на запуск некоторого кода на GPU. Смотрите мое редактирование. Кроме того, в последних версиях Matlab,forпетли стали на удивление быстрыми.

Похожие вопросы