function [results,times] = benchmark(count,test)
% BENCHMARK measurements in Matlab.
% This is a modification of BENCH, a routine developed by Stephen Lord,
% & originally written by Cleve Moler, MathWorks Inc.
% Though not specifically indicated, many lines of code that are used
% here were taken directly from BENCH.
% "count" is the number of times to run each test.
% if "count"=0, then only results from the database is shown.
% "test" is an integer [or array] selecting the tests to be performed
% from the 6 tests as follows: (e.g.[1,3,6])
% 1:LU 2:FFT 3:ODE 4:Sparse 5:2-D 6:3-D 7:All (default)
% "times" is an array with the actual times for each test execution.
% "results" is a summary of "times", 1st row has means & 2nd row has std values.
% The first set of times is dropped from "results" (unless "count"=1)
% since it may be affected by compile times.
% Care has been taken to insure that measurement times are comparable to the
% original BENCH, as much as possible of the orignal code during the timings
% was preserved. If there are any differences it is most likely to be
% with the graphics tests. Limited testing on three computer systems have not shown
% any significant differences with this code as compared to BENCH.
%
% Differences from BENCH
% 1.) Default value for count is 4.
% 2.) Added "results" summary output.
% 3.) The first test measurement is routinely dropped for "results".
% 4.) Only the mean values are displayed in the figures.
% 5.) User can select which test or tests are to be performed.
% 6.) Speed performance is rated in percent with the fastest machine as 100%.
% 7.) Bar graph only compares the sum of times for the selected tests.
% 8.) Test execution count is displayed.
%
% Note: The "sparse" benchmark has changed dramatically between ver.7.1 &
% 7.2 due to a significant increase in performance for Cholesky factorization!
%
% According to the original author:
% BENCH MATLAB Benchmark
% BENCH times six different MATLAB tasks and compares the execution
% speed with the speed of several other computers. The six tasks are:
%
% LU LAPACK, n = 1000. Floating point, regular memory access.
% FFT Fast Fourier Transform. Floating point, irregular memory access.
% ODE Ordinary diff. eqn. Data structures and M-files.
% Sparse Solve sparse system. Mixed integer and floating point.
% 2-D plot(fft(eye)). 2-D line drawing graphics.
% 3-D MathWorks logo. 3-D animated OpenGL graphics.
%
% A final bar chart shows speed, which is inversely proportional to
% time. Here, longer bars are faster machines, shorter bars are slower.
%
% The comparison data for other computers is stored in a text file:
% .../toolbox/matlab/demos/bench.dat
% Updated versions of this file are available from
% <a href="matlab:web('http://www.mathworks.com/matlabcentral/fileexchange/loadFile.do?objectId=1836&objectType=file#','-browser')">MATLAB Central</a>
% Note the link above opens your system web browser as defined by WEB.
%
% Fluctuations of five or 10 percent in the measured times of repeated
% runs on a single machine are not uncommon. Your own mileage may vary.
% Note by MIH:
% I have noted run times with occassional spikes that are
% significantly higher(2x) (arising from multitasking?).
% Repeated measurements (or larger count values) will smooth this out.
%
% This benchmark is intended to compare performance of one particular
% version of MATLAB on different machines. It does not offer direct
% comparisons between different versions of MATLAB. The tasks and
% problem sizes change from version to version.
%
% The LU and FFT tasks involve large matrices and long vectors.
% Machines with less than 64 megabytes of physical memory or without
% optimized Basic Linear Algebra Subprograms may show poor performance.
%
% The 2-D and 3-D tasks measure graphics performance, including software
% or hardware support for OpenGL. The command
% opengl info
% describes the OpenGL support available on a particular machine.
% Note by MIH:
% On one Windows XP system involving a laptop with a second monitor,
% it has been noted that the 3-D task hangs. The solution is to disable the
% extended desktop.
% Copyright 2006-2007 Mirtech, Inc.
% Bench Copyright 1984-2005 The MathWorks, Inc.
% $Revision: 5.37.4.12 $ $Date: 2005/06/21 19:24:12 $
% Modified by Mirko I. Hrovat, 2006/08/04 benchmark created
% Mirtech, Inc., email: mhrovat@email.com
% Modified by Mirko I. Hrovat, 2007/09/18
% can now read different column spacings of 2007 release of bench.dat
% added display of min and max speeds on bargraph based upon +-1 sd.
def_count = 4;
switch nargin
case 2
case 1
test=[];
case 0
test=[]; count=[];
otherwise
error (' Too many arguments!');
end
if isempty(count), count = def_count; end;
if isempty(test), test = 7; end;
fig1 = figure;
% if count is zero then only display database.
if count~=0,
ncount=1;
[ftitle,fplot,task]=setupfig(fig1);
times = zeros(count,6);
for k = 1:count
timestr = ' time.';
switch k
case 1
sufstr='st';
case 2
sufstr='nd';
case 3
sufstr='rd';
otherwise
sufstr='th';
end
countstr=[' ',int2str(k),sufstr,timestr];
subplot(fplot)
axis off
cla
if any(test==1)||any(test==7),
% LU, n = 1000.
subplot(ftitle)
set(task,'string',['LU',countstr])
drawnow
lu(0);
n = 1000;
randn('state',0);
A = randn(n,n);
X = A; %#ok Used to preallocate X
clear X
tic
X = lu(A); %#ok Result not used -- strictly for timing
times(k,1) = toc;
clear A
clear X
end
if any(test==2)||any(test==7),
% FFT, n = 2^20. Do it twice to roughly match LU time.
set(task,'string',['FFT',countstr])
drawnow
fft(0);
n = 2^20;
y = ones(1,n)+i*ones(1,n); %#ok Used to preallocate y
clear y
randn('state',1);
x = randn(1,n);
tic
y = fft(x); %#ok Result not used -- strictly for timing
clear y
y = fft(x); %#ok Result not used -- strictly for timing
times(k,2) = toc;
clear x
clear y
end
if any(test==3)||any(test==7),
% ODE. van der Pol equation, mu = 1
set(task,'string',['ODE',countstr])
drawnow
F = @vdp1;
y0 = [2; 0];
tspan = [0 eps];
[s,y] = ode45(F,tspan,y0); %#ok Used to preallocate s and y
tspan = [0 400];
tic
[s,y] = ode45(F,tspan,y0); %#ok Results not used -- strictly for timing
times(k,3) = toc;
clear s y
end
if any(test==4)||any(test==7),
% Sparse linear equations
set(task,'string',['Sparse',countstr])
drawnow
n = 300;
A = delsq(numgrid('L',n));
b = sum(A)';
s = spparms;
spparms('autommd',0);
tic
x = A\b; %#ok Result not used -- strictly for timing
times(k,4) = toc;
spparms(s);
clear A b
end
if any(test==5)||any(test==7),
% 2-D graphics
set(task,'string',['2-D',countstr])
drawnow
pause(0.2)
subplot(fplot)
set(fig1,'doublebuffer','on');
x = (0:1/256:1)';
plot(x,bernstein(x,0))
drawnow
tic
for j = 1:2
for n = [1:12 11:-1:2]
plot(x,bernstein(x,n))
drawnow
end
end
times(k,5) = toc;
pause(0.3)
set(fig1,'doublebuffer','off');
axis off
end
if any(test==6)||any(test==7),
% 3-D graphics. Vibrating logo.
% Gouraud lighting allows smooth motion with OpenGL.
% It is necessary to clear the figure to display the logo, otherwise
% run times for this test increase linearly with run number.
clf
[ftitle,fplot,task]=setupfig(fig1);
subplot(ftitle)
set(task,'string',['3-D',countstr])
drawnow
pause(0.2)
subplot(fplot)
% The following lines of code were taken from Logo.m
% These lines were included to reduce the number of open figures.
% Logo -- Plot the L-shaped membrane logo with MATLAB lighting.
% Copyright 1984-2005 The MathWorks, Inc.
% $Revision: 5.19.4.5.8.1 $ $Date: 2006/01/13 21:02:51 $
L = 40*membrane(1,25);
set(fplot,'Color',[0 0 0]);
logoax = axes('CameraPosition', [-193.4013 -265.1546 220.4819],...
'CameraTarget',[26 26 10], ...
'CameraUpVector',[0 0 1], ...
'CameraViewAngle',9.5, ...
'DataAspectRatio', [1 1 .9],...
'Position',[0.1 0 0.8 0.8], ...
'Visible','off', ...
'XLim',[1 51], ...
'YLim',[1 51], ...
'ZLim',[-13 40]);
surface(L, ...
'EdgeColor','none', ...
'FaceColor',[0.9 0.2 0.2], ...
'FaceLighting','phong', ...
'AmbientStrength',0.3, ...
'DiffuseStrength',0.6, ...
'Clipping','off',...
'BackFaceLighting','lit', ...
'SpecularStrength',1.1, ...
'SpecularColorReflectance',1, ...
'SpecularExponent',7, ...
'Tag','TheMathWorksLogo', ...
'parent',logoax);
light('Position',[40 100 20], ...
'Style','local', ...
'Color',[0 0.8 0.8], ...
'parent',logoax);
light('Position',[.5 -1 .4], ...
'Color',[0.8 0.8 0], ...
'parent',logoax);
% end of Logo
set(fplot,'color',[.8 .8 .8])
s = findobj(fig1, 'type','surf', 'tag', 'TheMathWorksLogo');
set(s,'facelighting','gouraud')
L1 = 40*membrane(1,25);
L2 = 10*membrane(2,25);
L3 = 10*membrane(3,25);
mu = sqrt([9.6397238445, 15.19725192, 2*pi^2]);
n = 40;
tic
for j = 0:n
t = 0.5*(1-j/n);
L = cos(mu(1)*t)*L1 + sin(mu(2)*t)*L2 + sin(mu(3)*t)*L3;
set(s,'zdata',L)
drawnow
end
times(k,6) = toc;
clear L L1 L2 L3 s
pause(0.3)
cla
end
end % loop on k
% calculate mean and standard deviations for execution times.
if count>2,
results=zeros(2,6);
numtimes=size(times,1)-1;
results(1,:)=mean(times(2:end,:));
results(2,:)=std(times(2:end,:));
else
numtimes=1;
if count==2,
results=times(2,:);
else
warning ('BENCHMARK:note',...
'First execution of program may produce slower times, use count>1.')
results=times(1,:);
end
end % if count>2
else
setupfig(fig1);
ncount=0;
results=[];
times=[];
end % if on count~=0
% Compare with other machines. Get latest data file, bench.dat, from
% MATLAB Central at the URL
if exist('bench.dat','file') ~= 2
warning('BENCHMARK:note',...
'Comparison data in file toolbox/matlab/demos/bench.dat not available.')
close(fig1);
return
end
fp = fopen('bench.dat');
% Skip over headings in first six lines.
for k = 1:5
fgetl(fp);
end
g = fgetl(fp); % get heading in sixth row to get column spacing
lastcol = strfind(g,'LU ')-1; %get last column number for computer description
% Read the comparison data
specs = {};
T = [];
details = {};
g = fgetl(fp);
m = 0;
while length(g) > 1
m = m+1;
specs{m} = g(1:lastcol); %#ok
T(m,:) = sscanf(g(lastcol+1:end),'%f')'; %#ok
details{m} = fgetl(fp); %#ok
g = fgetl(fp);
end
fclose(fp); % Close the data file
% Add the current machine and sort
% ncount=1 if measurements have been made, 0 otherwise
if ncount>0,
T = [T; results(1,:)];
specs{m+1} = ['This machine ',num2str(numtimes,'%3.0f'),' measurements'];
details{m+1} = ['It''s your machine running MATLAB ' version];
end
this = [zeros(m,1);ones(ncount,1)];
if any(test==7),
whichtest=ones(1,6);
else
whichtest=zeros(1,6);
whichtest(test)=1;
end
totals=(whichtest*T')'; % sum up only the selected tests
speeds = 100*min(totals)./totals;
if ncount>0 && numtimes>1,
lu_speed = (whichtest*[results(1,:)-results(2,:); results(1,:)+results(2,:)]')';
lu_speed = 100*min(totals)./lu_speed;
end
specs2=specs;
if ncount>0,
specs2{m+1}=['This machine ',num2str(speeds(m+ncount),'%4.1f'),'% '];
end
[speeds,k] = sort(speeds);
specs = specs(k);
specs2=specs2(k);
details = details(k);
T = T(k,:);
this = this(k);
measpos=find(this);
% Horizontal bar chart. Highlight this machine with another color.
clf(fig1)
% stretch figure to account for length & height of text
svunits=get(fig1,'Units');
set(fig1,'Units','normalized')
pos1=get(fig1,'Position');
set(fig1,'Position',pos1.*[1,1,0.6+(lastcol/82),0.2+m/15]) % m has #computers
set(fig1,'Units',svunits)
hax2 = axes('position',[.41 .10 .55 .80],'parent',fig1);
barh(hax2,speeds.*(1-this),'y')
hold(hax2,'on')
if ncount>0 && numtimes>1,
y=zeros(size(speeds));
y(measpos)=lu_speed(1);
barh(hax2,y,'r')
y(measpos)=lu_speed(2);
barh(hax2,y,'m')
else
barh(hax2,speeds.*this,'m')
end
set(hax2,'xlim',[0 100],'xtick',0:10:100)
if all(whichtest),
title(hax2,'Relative Speed for All Tests')
else
title(hax2,['Relative Speed for Test No. ',int2str(test)])
end
axis(hax2,[0 100 0 m+ncount+1])
set(hax2,'ytick',1:m+ncount)
set(hax2,'yticklabel',specs2,'fontsize',9)
% Display report in second figure
fig2 = figure('pos',get(fig1,'pos')+[50 -150 50 0], 'menubar','none', ...
'numbertitle','off','name','MATLAB Benchmark');
% Defining layout constants - change to adjust 'look and feel'
% The names of the tests
TestNames = {'LU', 'FFT', 'ODE', 'Sparse', '2-D', '3-D'};
% Number of test columns
NumTests = size(TestNames, 2);
NumRows = m+ncount+1; % Total number of rows + header (1) + number of results (1)
TopMargin = 0.05; % Margin between top of figure and title row
BotMargin = 0.20; % Margin between last test row and bottom of figure
LftMargin = 0.03; % Margin between left side of figure and Computer Name
RgtMargin = 0.03; % Margin between last test column and right side of figure
CNWidth = 0.350; % Width of Computer Name column
MidMargin = 0.03; % Margin between Computer Name column and first test column
HBetween = 0.025; % Distance between two rows of tests
WBetween = 0.015; % Distance between two columns of tests
% Width of each test column
TestWidth = (1-LftMargin-CNWidth-MidMargin-RgtMargin-(NumTests-1)*WBetween)/NumTests;
% Height of each test row
RowHeight = (1-TopMargin-(NumRows-1)*HBetween-BotMargin)/NumRows;
% Beginning of first test column
BeginTestCol = LftMargin+CNWidth+MidMargin;
% Retrieve the background color for the figure
bc = get(fig2,'Color');
YourMachineColor = [0 0 1];
% Create headers
% Computer Name column header
uicontrol('Style', 'text', 'Units', 'normalized', ...
'Position', [LftMargin 1-TopMargin-RowHeight CNWidth RowHeight],...
'String', 'Computer Type', 'BackgroundColor', bc, 'Tag', 'Computer_Name','FontWeight','bold');
% Test name column header
for k=1:NumTests
uicontrol('Style', 'text', 'Units', 'normalized', ...
'Position', [BeginTestCol+(k-1)*(WBetween+TestWidth) 1-TopMargin-RowHeight TestWidth RowHeight],...
'String', TestNames{k}, 'BackgroundColor', bc, 'Tag', TestNames{k}, 'FontWeight', 'bold');
end
% For each computer
for k=1:NumRows-1
VertPos = 1-TopMargin-k*(RowHeight+HBetween)-RowHeight;
if this(NumRows - k)
thecolor = YourMachineColor;
else
thecolor = [0 0 0];
end
% Computer Name row header
uicontrol('Style', 'text', 'Units', 'normalized', ...
'Position', [LftMargin VertPos CNWidth RowHeight],...
'String', specs{NumRows-k}, 'BackgroundColor', bc, 'Tag', specs{NumRows-k},...
'TooltipString', details{NumRows-k}, 'HorizontalAlignment', 'left', ...
'ForegroundColor', thecolor);
% Test results for that computer
for n=1:NumTests
uicontrol('Style', 'text', 'Units', 'normalized', ...
'Position', [BeginTestCol+(n-1)*(WBetween+TestWidth) VertPos TestWidth RowHeight],...
'String', sprintf('%.4f',T(NumRows-k, n)), 'BackgroundColor', bc, ...
'Tag', sprintf('Test_%d_%d',NumRows-k,n), 'ForegroundColor', thecolor);
end
end
% Warning text
uicontrol('Style', 'text', 'Units', 'normalized', ...
'Position', [0.01 0.01 0.98 BotMargin-0.02], 'BackgroundColor', bc, 'Tag', 'Disclaimer', ...
'String', sprintf('%s\n%s\n%s','Place the cursor near a computer name for system and version details. Before using', ...
'this data to compare different versions of MATLAB, or to download an updated timing data file,',...
'see the help for the benchmark function by typing ''help benchmark'' at the MATLAB prompt.'));
% ----------------------------------------------- %
function B = bernstein(x,n)
% BERNSTEIN Generate Bernstein polynomials.
% B = bernstein(x,n) is a length(x)-by-n+1 matrix whose columns
% are the Bernstein polynomials of degree n evaluated at x,
% B_sub_k(x) = nchoosek(n,k)*x.^k.*(1-x).^(n-k), k = 0:n.
x = x(:);
B = zeros(length(x),n+1);
B(:,1) = 1;
for k = 2:n+1
B(:,k) = x.*B(:,k-1);
for j = k-1:-1:2
B(:,j) = x.*B(:,j-1) + (1-x).*B(:,j);
end
B(:,1) = (1-x).*B(:,1);
end
% ----------------------------------------------- %
function [ftitle,fplot,task]=setupfig(fig1)
% SETUPFIG sets up the main figure used for the benchmark tests.
set(fig1,'pos','default','menubar','none','numbertitle','off', ...
'name','MATLAB Benchmark')
ftitle=subplot(5,5,(1:5));
axis off
text(.5,.8,'Executing MATLAB Benchmark','horizontal','center','fontsize',18)
task = text(.50,.2, '','horizontal','center','fontsize',18);
drawnow
fplot=subplot(5,5,6:25);
axis off
% ----------------------------------------------- %