MATLAB Parallel Toolbox для запуска двух отдельных функций на двух разных ядрах - PullRequest
0 голосов
/ 14 апреля 2011

У меня есть скрипт MATLAB, выполняющий две копии одной и той же функции, и я хочу запустить их параллельно на двух разных ядрах.

Это функция, которую я вызываю

function [outputVector] = ParallelPitchShift(inputVector, windowSize, hopSize, step)

%% Parameters

% Window size
winSize = windowSize;
% Space between windows
hop = hopSize;
% Pitch scaling factor
alpha = 2^(step/12);

% Intermediate constants
hopOut = round(alpha*hop);

% Hanning window for overlap-add
wn = hann(winSize*2+1);
wn = wn(2:2:end);

%% Source file

x = inputVector;

% Rotate if needed
if size(x,1) < size(x,2)

    x = transpose(x);

end

x = [zeros(hop*3,1) ; x];

%% Initialization

% Create a frame matrix for the current input
[y,numberFramesInput] = createFrames(x,hop,winSize);

% Create a frame matrix to receive processed frames
numberFramesOutput = numberFramesInput;
outputy = zeros(numberFramesOutput,winSize);

% Initialize cumulative phase
phaseCumulative = 0;

% Initialize previous frame phase
previousPhase = 0;

for index=1:numberFramesInput

%% Analysis

    % Get current frame to be processed
    currentFrame = y(index,:);

    % Window the frame
    currentFrameWindowed = currentFrame .* wn' / sqrt(((winSize/hop)/2));

    % Get the FFT
    currentFrameWindowedFFT = fft(currentFrameWindowed);

    % Get the magnitude
    magFrame = abs((currentFrameWindowedFFT));

    % Get the angle
    phaseFrame = angle(currentFrameWindowedFFT);

%% Processing    

    % Get the phase difference
    deltaPhi = phaseFrame - previousPhase;

    previousPhase = phaseFrame;

    % Remove the expected phase difference
    deltaPhiPrime = deltaPhi - hop * 2*pi*(0:(winSize-1))/winSize;

    % Map to -pi/pi range
    deltaPhiPrimeMod = mod(deltaPhiPrime+pi, 2*pi) - pi;

    % Get the true frequency
    trueFreq = 2*pi*(0:(winSize-1))/winSize + deltaPhiPrimeMod/hop;

    % Get the final phase
    phaseCumulative = phaseCumulative + hopOut * trueFreq;    

    % Remove the 60 Hz noise. This is not done for now but could be
    % achieved by setting some bins to zero.

%% Synthesis    

    % Get the magnitude
    outputMag = magFrame;

    % Produce output frame
    outputFrame = real(ifft(outputMag .* exp(j*phaseCumulative)));

    % Save frame that has been processed
    outputy(index,:) = outputFrame .* wn' / sqrt(((winSize/hopOut)/2));

end

%% Finalize

% Overlap add in a vector
outputTimeStretched = fusionFrames(outputy,hopOut);

% Resample with linearinterpolation
outputTime = interp1((0:(length(outputTimeStretched)-1)),outputTimeStretched,(0:alpha:(length(outputTimeStretched)-1)),'linear');

% Return the result
outputVector = outputTime;

return

И это то, что я делаю, чтобы вызвать функцию

clear

x = wavread('x2.wav');

y1 = ParallelPitchShift(x,1024,256,7);

y2 = ParallelPitchShift(x,1024,256,12);

output = x(1:417000)' + y1(1:417000) + y2(1:417000);

sound(x,44100)

pause

sound(output,44100)

Возможно ли это сделать?Пожалуйста, дайте мне знать, спасибо!

Ответы [ 3 ]

2 голосов
/ 14 апреля 2011

Я не понимаю, что вы подразумеваете под двумя копиями одной и той же функции.Вы имели в виду два разных входных аргумента для одной и той же функции или что две функции совершенно разные?

Я предполагаю, что это первое (потому что это то, что вы написали).В этом случае попробуйте

somethingVector=[something, something2];
parfor i=1:2
    function(something(i),otherArgs)
end

Помните, что перед использованием цикла parfor вы должны открыть пул работников, например:

matlabpool('open',2)
1 голос
/ 15 апреля 2011

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

Оператор spmd позволяет вам определить блок кода для одновременного запуска несколько лабораторий.

Чтобы использовать его, вы должны сначала определить matlabpool.

matlabpool 3

Это автоматически создает «скрытую» переменную в рабочей области с именем labindex , которая указывает, какая лаборатория в данный момент выполняет работу.

labindex

ans =

     1 

Когда мы используем spmd , мы выполняем наш код параллельно во всех лабораториях, открытых matlabpool .

spmd 
labindex
end
Lab 1: 

  ans =

       1

Lab 2: 

  ans =

       2

Lab 3: 

  ans =

       3

Мы можем использовать labindex , чтобы указать разные входные данные для одной и той же функции и запускать все параллельно. Если у нас есть две разные матрицы и мы хотим найти собственные значения параллельно, мы можем сделать

M = {rand(10) rand(20)}; %Put matrices into cell for easy access
spmd
  if labindex < 3  %We only have two matrices, so only need two labs
     E = eig(M(labindex));
  end
end
E
E =

   Lab 1: class = double, size = [10   1]
   Lab 2: class = double, size = [20   1]
   Lab 3: No data
0 голосов
/ 15 апреля 2011

Я протестировал параллельный набор инструментов и в итоге не купил его специально, потому что вы не можете контролировать, какие функции работают на каком ядре.Поэтому, если вы запускаете несколько рабочих (используя matlabpool()) и пытаетесь отправить обработку функции определенному рабочему / пулу, она не будет работать.Однако использование parfor будет равномерно распределять рабочую нагрузку по ядрам, чтобы оптимизировать время обработки.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...