How to parallelize MATLAB function on the CPU
3 次查看(过去 30 天)
显示 更早的评论
I have a MATLAB function and a dataset that I would like to run in parallel on the CPU. Specifically, I would like to compare the performance of running the function with and without parallelization
I also attached my Dataset below
How Can i do that in MATLAB
load('Dataset.mat')
clusternumber = 6;
function [Score] = Scorefunction(Dataset,clusternumber)
dataset_len = size(Dataset,1);
Score = zeros(1,clusternumber);
for j=1:clusternumber
[cluster_assignments,centroids] = kmeans(Dataset,j);
distance_within=zeros(dataset_len,1);
distance_between=Inf(dataset_len,j);
for i=1:dataset_len
for jj=1:j
boo=cluster_assignments==cluster_assignments(i);
Xsamecluster=Dataset(boo,:);
if size(Xsamecluster,1)>1
distance_within(i)=sum(sum((Dataset(i,:)-Xsamecluster).^2,2))/(size(Xsamecluster,1)-1);
end
boo1= cluster_assignments~=cluster_assignments(i);
Xdifferentcluster=Dataset(boo1 & cluster_assignments ==jj,:);
if ~isempty(Xdifferentcluster)
distance_between(i,jj)=mean(sum((Dataset(i,:)-Xdifferentcluster).^2,2));
end
end
end
minavgDBetween = min(distance_between, [], 2);
silh = (minavgDBetween - distance_within) ./ max(distance_within,minavgDBetween);
Score(j) =mean(silh);
end
end
回答(2 个)
Arka
2023-3-10
Hi,
You can benefit from parallel computing by using the functions provided in the Parallel Computing Toolbox.
I have modified the code to include the required functions:
load('Dataset.mat')
clusternumber = 6;
% Create independent job on cluster
c = parcluster;
job = createJob(c);
% Create new task in the job
%for i = 1:10
task = createTask(job, @Scorefunction, 1, {Dataset, clusternumber});
%end
submit(job); % run the job
wait(job); % wait for the job to end
results = fetchOutputs(job); % get the results
disp(results);
delete(job); % delete the job
function [Score] = Scorefunction(Dataset,clusternumber)
dataset_len = size(Dataset,1);
Score = zeros(1,clusternumber);
for j=1:clusternumber
[cluster_assignments,centroids] = kmeans(Dataset,j);
distance_within=zeros(dataset_len,1);
distance_between=Inf(dataset_len,j);
for i=1:dataset_len
for jj=1:j
boo=cluster_assignments==cluster_assignments(i);
Xsamecluster=Dataset(boo,:);
if size(Xsamecluster,1)>1
distance_within(i)=sum(sum((Dataset(i,:)-Xsamecluster).^2,2))/(size(Xsamecluster,1)-1);
end
boo1= cluster_assignments~=cluster_assignments(i);
Xdifferentcluster=Dataset(boo1 & cluster_assignments ==jj,:);
if ~isempty(Xdifferentcluster)
distance_between(i,jj)=mean(sum((Dataset(i,:)-Xdifferentcluster).^2,2));
end
end
end
minavgDBetween = min(distance_between, [], 2);
silh = (minavgDBetween - distance_within) ./ max(distance_within,minavgDBetween);
Score(j) =mean(silh);
end
end
To learn more about Parallel Computing Toolbox and its functions, please check out the MathWorks documentation links below:
4 个评论
Arka
2023-3-10
编辑:Arka
2023-3-10
You can use parfor as well, but my implementation took up ~10 seconds less time than parfor. I assume the pool of workers takes some extra time to get created.
I have altered the code to add the stopwatch timer like so:
tic
task = createTask(job, @Scorefunction, 1, {Dataset, clusternumber});
submit(job); % run the job
wait(job); % wait for the job to end
results = fetchOutputs(job); % get the results
toc
This will print the time elapsed between the start of the timer and end of the timer. You can do the same thing for the sequential processing function call, and then compare the times.
To learn more about the stopwatch timer, please check out the MathWorks documentation links below:
Raymond Norris
2023-3-10
As @Arka mentioned, consider using the Parallel Computing Toolbox. In your case, I would suggest looking at rewriting your outer for-loop as a parfor.
To begin with, let's write a helper script
function t = run_me
load('Dataset.mat')
clusternumber = 6;
t0 = tic;
Scorefunction(Dataset,clusternumber);
t = toc(t0);
I'll run it once as is, then modify Scorefunction as such
for j=1:clusternumber
to
parfor j=1:clusternumber
Before I run it a second time, I started a parallel pool of 6 workers (the size of the pool should be a factor of the size of the parfor loop -- 6 in this case).
Here's my complete run, showing a speed up of 3.2 (the actual tic/toc should be directly around the parfor-loop, but I didn't want to modify your code more than I needed to).
>> t = run_me
t =
15.5585
>>
>> parpool('local',6);
Starting parallel pool (parpool) using the 'local' profile ...
Connected to the parallel pool (number of workers: 6).
>> tparallel = run_me
tparallel =
4.8057
>>
>> t/tparallel
ans =
3.2375
0 个评论
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Startup and Shutdown 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!