How is matlab using 60% of my CPU?

조회 수: 4 (최근 30일)
Jacob Bresler
Jacob Bresler 2016년 6월 1일
댓글: Jacob Bresler 2016년 6월 1일
I am currently running a code that is not written for parallel computing (I don't even have that toolbox on this computer) and it is somehow taking ~60% of my available CPU power, I have an Intel i7-6820HK which has 4 physical cores and hyperthreading so it is somehow taking an effective 4.8 cores worth of computing power, here is the code for reference (there is a main script and a function that it uses to deal with the unknown size of the matrices, I didn't write the function, I got it from someone here). It doesn't do this on my other computer which is much older and crappier (five year old macbook running windows 7 with an intel i7-3720QM) it maxes out at about 15% on that computer
%Jacob Bresler
clear
clc
m_0=.75; %given initial concentration
k=.01; %step size in time
%storage cell array for the matrices of concentration vectors rows have
%same a, columns have same lambda, and the third dimension in both store
%and x are for different values of h
store=cell(6,13,2);
store2=cell(6,13,2);
store3=cell(6,13,2);
store4=cell(6,13,2);
store5=cell(6,13,2);
r_store=cell(1,1,10);
%initializing values for loops
a_count=0;
l_count=0;
time=zeros(1,10);
M=matfile('NM_HW3');
M.Properties.Writable=true;
for d=100:100:1000
tic
e=d/100;
h=1/d;
r=0:h:1;
sr=d+1;
%setting the initial concentration vector
m_i=zeros(1,sr);
m_i(1,:)=m_0;
for a=1:.2:2 %a increases linearly from 1 to 2
l_p=0; %resetting the power for the lambda
a_count=a_count+1; %used for indexing in the storage array
lambda=1; %so following loop works
while lambda<=1000
lambda=10^l_p; %lambda increases exponentially from 10^0 to 10^3
l_p=l_p+.25; %increasing the power of the lambda for the next loop
%failsafe to break loop at lambda=1000
if lambda>1000
break
end
l_count=l_count+1; %used for indexing in the storage array
m_loop=m_i; %vector for current time and current iteration
%using outside function to speed the storage of the concentration
%vectors
m_s=growdata2;
m_s(m_i);
t=0; %initializing time at zero for every run through
while m_loop(1,1)>.2*m_0 %end condition given in problem statement
t=t+k; %increasing time by k for each time iteration
m_t_old=m_loop; %vector of concentrations for the previous time
%initializing for following loop
m_diff=1;
n=0;
%finding iterative convergence within time steps
while max(m_diff)>1e-6;
n=n+1; %increasing the iteration count within time step
m_n_old=m_loop; %vector of concentrations for previous iteration
D_n_old=1./(a.^m_n_old); % vector of D function for previous iteration
%setting boundary conditions for current loop vector
m_loop(1,sr)=m_0*exp(-lambda*t);
m_loop(1,1)=((h^2)*m_t_old(1,1)+6*k*D_n_old(1,1)*m_n_old...
(1,2))/(h^2+6*k*D_n_old(1,1));
for i=2:sr-1
D_r_old=1/(a^m_loop(i-1)); %D function for current iteration at point i-1
%I simply split up the large equation into 4 sets of
%numerator and denominator pairs for easier
%troubleshooting
n1=(h^2)*m_t_old(i);
d1=(h^2+2*k*D_n_old(i));
p1=n1/d1;
n2=k*(D_n_old(i+1)*(m_n_old(i+1)-m_loop(i-1))+...
D_r_old*(m_loop(i-1)-m_n_old(i+1)));
d2=(4*(h^2+2*k*D_n_old(i)));
p2=n2/d2;
n3=k*h*D_n_old(i)*(m_n_old(i+1)-m_loop(i-1));
d3=r(i)*(h^2+2*k*D_n_old(i));
p3=n3/d3;
n4=k*D_n_old(i)*(m_n_old(i+1)+m_loop(i-1));
d4=h^2+2*k*D_n_old(i);
p4=n4/d4;
m_loop(i)=p1+p2+p3+p4;
end
m_diff=abs(m_loop-m_n_old); %difference between current iteration and previous iteration for iterative convergence
end
m_s(m_loop); %sending current vector to outside function mentioned previously
end
if e==1||e==2
store{a_count,l_count,e}=m_s();
elseif e==3||e==4
store2{a_count,l_count,e-2}=m_s();
elseif e==5||e==6
store3{a_count,l_count,e-4}=m_s();
elseif e==7||e==8
store4{a_count,l_count,e-6}=m_s();
else
store5{a_count,l_count,e-8}=m_s();
end
clear m_s
[a_count,l_count,e]
end
l_count=0; %resetting the count for lambda
end
time(e)=toc;
if e==2
M.store=store;
clear store
elseif e==4
M.store2=store2;
clear store2
elseif e==6
M.store3=store3;
clear store3
elseif e==8
M.store4=store4;
clear store4
elseif e==10
M.store5=store5;
clear store5
end
a_count=0;
r_store{1,1,e}=r;
clear r h sr m_i
end
function funH=growdata2(appendmode,blocksize)
% incremental growth of an array by appending rows (or columns)
%
% usage always involves 3 steps
% (initial call): funH=growdata2;
% (growth call): funH(newdata)
% (unpacking call): A = funH();
%
% Alternative initial call:
% funH = growdata2(appendmode,blocksize);
%
% Note that the basic unpacking call, A = funH; will drain
% the data stored in the function handle funH. Future calls
% to funH will begin accumulation from an empty state.
%
%
% arguments: (input)
% appendmode - (OPTIONAL) specifies appending to rows or columns.
%
% appendmode == 'rows' --> append new data as rows
% of the final array.
%
% appendmode == 'columns' --> append new data as
% columns of the final array.
%
% DEFAULT: 'rows'
%
% blocksize - (OPTIONAL) specifies the initial block size to
% accumulate into. Larger blocksizes will result
% faster accumulation, but will grab larger chunks
% of memory at a time.
%
% DEFAULT: 20000
%
%
% arguments: (output)
% funH - function handle which will be used for the growth
% and terminal calls to unpack the grown array of
% data.
%
%
% Example usage 1:
%
% fun1 = growdata2;
% for i = 1:100000
% fun1(i)
% end
% A = fun1();
%
% A will have size [100000,1]
%
%
% Example usage 2:
%
% Note: growdata uses a function handle to a nested function,
% so multiple arrays may be grown at the same time, simply by
% assigning a different function name on the first call to
% growdata. We can also change the appending style for each
% instance.
%
% fun1 = growdata2; % append as new rows by default
% fun2 = growdata2('columns'); % append as new columns
% fun3 = growdata2('rows'); % append as new rows
% for i = 1:10000
% fun1(rand(2,3))
% fun2(sin(rand(2,1)))
% fun3(rand(round(rand(1)*2),2))
% end
% A = fun1();
% B = fun2();
% C = fun3();
%
% In this case, A will have final size [20000,3], B will
% have size [2, 10000], and C will have a ramdom number of
% rows, with 2 columns.
%
%
% see also: cat, horzcat, vertcat
%
%
% Author: John D'Errico
% e-mail: woodchips@rochester.rr.com
% Release: 1.1
% Release date: 2/28/07
% when growdata is called, a function handle to a nested
% function is returned.
% first, set up the variables we will need to remember
% check for appendmode
if (nargin<1) || isempty(appendmode)
appendmode = 'rows';
end
valid = {'rows','columns'};
ind = strmatch(appendmode,valid);
if isempty(ind)
error 'Appendmode must be ''rows'' or ''columns'' or any contraction'
end
% appendmode == 0 --> append as rows
% appendmode == 1 --> append as columns
appendmode = ind - 1;
% default for blocksize
if (nargin<2) || isempty(blocksize)
blocksize = 20000;
end
% default number of rows in each cell
rowcount = blocksize;
% we don't know how many columns
columncount = NaN;
celldata = {zeros(rowcount,0)};
n = 0;
totalrows = 0;
% Return a handle to the function which will actually
% do all the work
funH = @growthfun;
% ====================================================
% nested function definition
function A = growthfun(newdata)
% is this a growth call, or a final unpacking call?
if (nargout==0) && (nargin>0)
% its a growth step
% if appendmode says to use columns, then transpose the
% data, append as rows. we will re-transpose at the very
% end to undo this.
if appendmode
newdata = newdata';
end
% size of the appending data
[r,c]=size(newdata);
% was this the first call after initialization?
if isnan(columncount)
% first time called, we need to know the number
% of columns to expect
columncount = c;
if r < rowcount
% rowcount is large enough for now
celldata = {[newdata;zeros(rowcount - r,columncount)]};
n = r;
totalrows = r;
else
% the first call overwhelmed rowcount, so make it larger
n = 0;
totalrows = r;
rowcount = 2*r;
celldata = {newdata, zeros(rowcount,columncount)};
end
else
% its an appending call after we have seen some data
if c ~= columncount
error '# of columns are incompatible for appending to this data'
end
% stuff into the last cell
if (n+r)<rowcount
celldata{end}(n+(1:r),:) = newdata;
n = n+r;
totalrows = totalrows + r;
elseif (n+r)==rowcount
% exactly filled that last cell, so add a new
% (empty) cell on to the end
celldata{end}(n+(1:r),:) = newdata;
celldata{end+1} = zeros(rowcount,columncount);
totalrows = totalrows + r;
n = 0;
else
% we will overfill the last cell
s = rowcount - n;
celldata{end}(n+(1:s),:) = newdata(1:s,:);
celldata{end+1} = newdata((s+1):end,:);
totalrows = totalrows + r;
n = size(celldata{end},1);
if n>=rowcount
% enlarge the cell size
rowcount = n;
celldata{end+1} = zeros(rowcount,columncount);
n = 0;
end
end
end
elseif (nargin==0)
% its an unpacking step
% first drop any extraneous rows in the last cell
celldata{end} = celldata{end}(1:n,:);
% concatenate
if ~appendmode
% as rows
A = cat(1,celldata{:});
else
% as columns, but we did it as rows, so transpose
A = cat(1,celldata{:})';
end
% and clear the data to return some memory
celldata = {zeros(rowcount,columncount)};
elseif (nargout>0) && (nargin>0)
% cannot both append and unpack in the same step.
error 'Cannot append more data and unpack in the same call'
end
end % end nested function
end % end main fun

답변 (1개)

James Tursa
James Tursa 2016년 6월 1일
Without looking at your code in any detail I will offer this comment. Many MATLAB functions (such as matrix multiplication, element-wise multiplication, etc) are multi-threaded in the background. You don't have to have the Parallel Computing Toolbox to get this ... they are simply coded that way at the low level and you get it automatically. Also, over the years MATLAB has improved this multi-threading capability and has added more background multi-threading capability. It is quite possible that your code is simply getting the benefit of this background multi-threading on one machine but not the other.
  댓글 수: 1
Jacob Bresler
Jacob Bresler 2016년 6월 1일
I don't understand how... they both have 4 real/8 virtual cores and are both running 64 bit matlab 2016a. The macbook is actually running a version with some extra trial plugins like parallel computing that the newer computer isn't. I am also not running any matrix multiplications, everything is computed from one end of the row to the next and then to the next row (the code is a partially implicit numerical integrator function that I wrote for a class). I did notice that as the vectors get larger the cpu draw does increase (for 1x101 vectors it is much lower than 1x701 for instance on both computers but the difference is significantly higher on the newer machine ~15%-~20% on the macbook, ~20%-~70% on the new machine). This could be the case but I am not completely convinced.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 MATLAB Coder에 대해 자세히 알아보기

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by