我有一个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)
可以这样做吗?请让我知道谢谢!
答案 0 :(得分:2)
我不明白你所说的相同功能的两个副本是什么意思。你是指同一个函数的两个不同的输入参数,还是两个函数完全不同?
我假设它是前者(因为那是你写的)。在这种情况下,请尝试
somethingVector=[something, something2];
parfor i=1:2
function(something(i),otherArgs)
end
请记住,在使用parfor
循环之前,您应该像这样打开一个工作池:
matlabpool('open',2)
答案 1 :(得分:1)
您想要的是并行计算工具箱中的单程序多数据或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 :(得分:0)
我测试了并行工具箱并最终没有专门购买它,因为你无法控制在哪个核心上运行的功能。因此,如果启动多个worker(使用matlabpool()
)并尝试将函数处理发送到特定的worker / pool,它将无法工作。但是,使用parfor
会将工作负载均匀分布在核心上,以便优化处理时间。
对于我想要做的事情,解决方案是让不同的matlab会话运行。希望CPU将下一个会话分配给另一个CPU