2011-04-14 60 views
0

我有一個運行同一函數的兩個副本的MATLAB腳本,我想在兩個不同的內核上並行運行它們。用於在兩個不同內核上運行兩個獨立函數的MATLAB Parallel Toolbox

這功能我打電話

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) 

是否有可能做到這一點?請讓我知道,謝謝!

回答

1

想要的是Single Parallel Multiple Data或Parallel Computing工具箱中的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 
2

我不明白你的意思是兩個副本的功能是否一樣。你是指同一個函數有兩個不同的輸入參數,或者這兩個函數完全不同?

我假設它的前者(因爲這是你寫的)。在這種情況下,嘗試

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

記住,您使用的是parfor循環之前,你應該打開的工人池像這樣:

matlabpool('open',2) 
+0

我試過了,但功能有一個用於內部的循環不能並行... MATLAB給了我一個錯誤。 – user123668 2011-04-14 03:52:27

+0

是否可以在不使用parfor的情況下完成? – user123668 2011-04-14 03:52:59

+0

你有沒有試過在另一個函數中包裝你的代碼的麻煩部分? – abcd 2011-04-14 04:22:06

0

我測試過並聯的工具箱並最終漲不買它特別是因爲你無法控制在哪個內核上運行的功能。因此,如果啓動多個工作人員(使用matlabpool())並嘗試將函數處理髮送給特定的工作人員/池,則該工作將無法工作。然而,使用parfor將在覈心上均勻分配工作負載,以優化處理時間。

對於我正在嘗試做的,解決方案是運行不同的matlab會話。希望CPU將下一個會話分配給另一個CPU