Accelerate Code Using fiaccel
Speeding Up Fixed-Point Execution with fiaccel
You can convert fixed-point MATLAB® code to MEX functions using fiaccel
. The generated MEX functions contain optimizations to automatically
accelerate fixed-point algorithms to compiled C/C++ code speed in MATLAB. The fiaccel
function can greatly increase the execution
speed of your algorithms.
Running fiaccel
The basic command is:
fiaccel M_fcn
By default, fiaccel
performs the following actions:
Searches for the function
M_fcn
stored in the fileM_fcn
.m
as specified in Compile Path Search Order.Compiles
M_fcn
to MEX code.If there are no errors or warnings, generates a platform-specific MEX file in the current folder, using the naming conventions described in File Naming Conventions.
If there are errors, does not generate a MEX file, but produces an error report in a default output folder, as described in Generated Files and Locations.
If there are warnings, but no errors, generates a platform-specific MEX file in the current folder, but does report the warnings.
You can modify this default behavior by specifying one or more compiler options with
fiaccel
, separated by spaces on the
command line.
Generated Files and Locations
fiaccel
generates files in the following locations:
Generates: | In: |
---|---|
Platform-specific MEX files | Current folder |
code generation reports (if errors or warnings occur during compilation) | Default output folder: fiaccel/mex/M_fcn_name/html |
You can change the name and location of generated files by using the options
-o
and -d
when you run fiaccel
.
In this example, you will use the fiaccel
function to compile
different parts of a simple algorithm. By comparing the run times of the two cases, you will
see the benefits and best use of the fiaccel
function.
Compare Run Times When Accelerating Different Algorithm Parts
This example shows how to use the fiaccel
function to compile different parts of a simple algorithm.
The algorithm used throughout this example replicates the functionality of the MATLAB sum
function, which sums the columns of a matrix.
type fi_matrix_column_sum.m
function B = fi_matrix_column_sum(A) % Sum the columns of matrix A. % Copyright 2008-2023 The MathWorks, Inc. %#codegen [m,n] = size(A); w = get(A,'WordLength') + ceil(log2(m)); f = get(A,'FractionLength'); B = fi(zeros(1,n),true,w,f,fimath(A)); for j = 1:n for i = 1:m B(j) = B(j) + A(i,j); end end
Trial 1: Best Performance
The best way to speed up the execution of the algorithm is to compile the entire algorithm using the fiaccel
function. To evaluate the performance improvement provided by the fiaccel
function when the entire algorithm is compiled, run the following code.
The first portion of code executes the algorithm using only MATLAB functions.
fipref('NumericTypeDisplay','short'); A = fi(randn(1000,10)); tic B = fi_matrix_column_sum(A); t_matrix_column_sum_m = toc
t_matrix_column_sum_m = 1.8325
The second portion of the code compiles the entire algorithm using the fiaccel function. The MATLAB tic
and toc
functions keep track of the run times for each method of execution.
fiaccel fi_matrix_column_sum -args {A} tic B = fi_matrix_column_sum_mex(A); t_matrix_column_sum_mex = toc
t_matrix_column_sum_mex = 0.1048
Trial 2: Worst Performance
Compiling only the smallest unit of computation using the fiaccel
function leads to much slower execution. In some cases, the overhead that results from calling the mex
function inside a nested loop can cause even slower execution than using MATLAB functions alone. To evaluate the performance of the mex
function when only the smallest unit of computation is compiled, run the following code.
The first portion of code executes the algorithm using only MATLAB functions.
tic [m,n] = size(A); w = get(A,'WordLength') + ceil(log2(m)); f = get(A,'FractionLength'); B = fi(zeros(1,n),true,w,f); for j = 1:n for i = 1:m B(j) = fi_scalar_sum(B(j),A(i,j)); % B(j) = B(j) + A(i,j); end end t_scalar_sum_m = toc
t_scalar_sum_m = 7.9232
The second portion of the code compiles the smallest unit of computation with the fiaccel
function, leaving the rest of the computations to MATLAB.
fiaccel fi_scalar_sum -args {B(1),A(1,1)} tic [m,n] = size(A); w = get(A,'WordLength') + ceil(log2(m)); f = get(A,'FractionLength'); B = fi(zeros(1,n),true,w,f); for j = 1:n for i = 1:m B(j) = fi_scalar_sum_mex(B(j),A(i,j)); % B(j) = B(j) + A(i,j); end end t_scalar_sum_mex = toc
t_scalar_sum_mex = 3.4004
Ratio of Times
Compare the results of Trial 1 and Trial 2. Your computer may record different times, but the ratios should be approximately the same. There is a significant difference in ratios between the trial where the entire algorithm was compiled using fiaccel
(t_matrix_column_sum_mex.m
) and where only the scalar sum was compiled (t_scalar_sum_mex.m
). Even the file with no fiaccel
compilation (t_matrix_column_sum_m
) did better than when only the smallest unit of computation was compiled using fiaccel
(t_scalar_sum_mex
).
t_scalar_sum_mex/t_matrix_column_sum_mex
ans = 32.4530
t_scalar_sum_mex/t_matrix_column_sum_m
ans = 1.8556
t_matrix_column_sum_m/t_matrix_column_sum_mex
ans = 17.4890
t_scalar_sum_m/t_scalar_sum_mex
ans = 2.3301
Trial 1: Best Performance
The best way to speed up the execution of the algorithm is to compile the entire
algorithm using the fiaccel
function. To evaluate the performance
improvement provided by the fiaccel
function when the entire algorithm
is compiled, run the following code.
The first portion of code executes the algorithm using only MATLAB functions. The second portion of the code compiles the entire algorithm
using the fiaccel
function. The MATLAB
tic
and toc
functions keep track of the run times
for each method of execution.
% MATLAB fipref('NumericTypeDisplay','short'); A = fi(randn(1000,10)); tic B = fi_matrix_column_sum(A) t_matrix_column_sum_m = toc % fiaccel fiaccel fi_matrix_column_sum -args {A} tic B = fi_matrix_column_sum_mex(A); t_matrix_column_sum_mex = toc
Trial 2: Worst Performance
Compiling only the smallest unit of computation using the fiaccel
function leads to much slower execution. In some cases, the overhead that results from
calling the mex
function inside a nested loop can cause even slower
execution than using MATLAB functions alone. To evaluate the performance of the mex
function when only the smallest unit of computation is compiled, run the following code.
The first portion of code executes the algorithm using only MATLAB functions. The second portion of the code compiles the smallest unit of
computation with the fiaccel
function, leaving the rest of the
computations to MATLAB.
% MATLAB tic [m,n] = size(A); w = get(A,'WordLength') + ceil(log2(m)); f = get(A,'FractionLength'); B = fi(zeros(1,n),true,w,f); for j = 1:n for i = 1:m B(j) = fi_scalar_sum(B(j),A(i,j)); % B(j) = B(j) + A(i,j); end end t_scalar_sum_m = toc % fiaccel fiaccel fi_scalar_sum -args {B(1),A(1,1)} tic [m,n] = size(A); w = get(A,'WordLength') + ceil(log2(m)); f = get(A,'FractionLength'); B = fi(zeros(1,n),true,w,f); for j = 1:n for i = 1:m B(j) = fi_scalar_sum_mex(B(j),A(i,j)); % B(j) = B(j) + A(i,j); end end t_scalar_sum_mex = toc
Ratio of Times
A comparison of Trial 1 and Trial 2 appears in the following table. Your computer may
record different times than the ones the table shows, but the ratios should be
approximately the same. There is an extreme difference in ratios between the trial where
the entire algorithm was compiled using fiaccel
(t_matrix_column_sum_mex.m
) and where only the scalar sum was
compiled (t_scalar_sum_mex.m
). Even the file with no
fiaccel
compilation (t_matrix_column_sum_m
) did
better than when only the smallest unit of computation was compiled using
fiaccel
(t_scalar_sum_mex
).
X (Overall Performance Rank) | Time | X/Best | X_m/X_mex |
---|---|---|---|
Trial 1: Best Performance | |||
t_matrix_column_sum_m (2) | 1.99759 | 84.4917 | 84.4917 |
t_matrix_column_sum_mex (1) | 0.0236424 | 1 | |
Trial 2: Worst Performance | |||
t_scalar_sum_m (4) | 10.2067 | 431.71 | 2.08017 |
t_scalar_sum_mex (3) | 4.90664 | 207.536 |
Data Type Override Using fiaccel
To
turn data type override on, type the following command at the MATLAB prompt after running the reset(fipref)
command:
fipref('DataTypeOverride','TrueDoubles')
This command tells Fixed-Point Designer™ software to create all fi
objects with type
fi
double
. When you compile the code using the fiaccel
command,
the resulting MEX-function uses floating-point data.
Specifying Default fimath
Values for MEX Functions
MEX functions generated with fiaccel
use the MATLAB default global fimath
. The MATLAB factory default global fimath
has the following properties:
RoundingMethod: Nearest OverflowAction: Saturate ProductMode: FullPrecision SumMode: FullPrecision
When running MEX functions that depend on the MATLAB default fimath
value, do not change this value during your
MATLAB session. Otherwise, MATLAB generates a warning, alerting you to a mismatch between the compile-time and
run-time fimath
values. For example, create the following MATLAB function:
function y = test %#codegen y = fi(0);
test
constructs a fi
object without
explicitly specifying a fimath
object. Therefore, test
relies on the default fimath
object in effect at compile time. Generate the MEX function test_mex
to use the factory setting of the
MATLAB default
fimath
.
resetglobalfimath;
fiaccel test
fiaccel
generates a MEX function, test_mex
, in the current folder.Run
test_mex
.
test_mex
ans = 0 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 15
Modify the MATLAB default fimath
value so it no longer matches the setting
used at compile time.
F = fimath('RoundingMethod','Floor'); globalfimath(F);
Clear the MEX function from memory and rerun it.
clear test_mex
test_mex
testglobalfimath_mex Warning: This function was generated with a different default fimath than the current default. ans = 0 DataTypeMode: Fixed-point: binary point scaling Signedness: Signed WordLength: 16 FractionLength: 15
fimath
properties from your algorithm by
using types tables. For more information, see Separate Data Type Definitions from Algorithm.