MATLAB Language Performance and Benchmarking It's ok to be `single`!



The default data type for numeric arrays in MATLAB is double. double is a floating point representation of numbers, and this format takes 8 bytes (or 64 bits) per value. In some cases, where e.g. dealing only with integers or when numerical instability is not an imminent issue, such high bit depth may not be required. For this reason, it is advised to consider the benefits of single precision (or other appropriate types):

  • Faster execution time (especially noticeable on GPUs).
  • Half the memory consumption: may succeed where double fails due to an out-of-memory error; more compact when storing as files.

Converting a variable from any supported data type to single is done using:

sing_var = single(var);

Some commonly used functions (such as: zeros, eye, ones, etc.) that output double values by default, allow specifying the type/class of the output.

Converting variables in a script to a non-default precision/type/class:

As of July 2016, there exists no documented way to change the default MATLAB data type from double.

In MATLAB, new variables usually mimic the data types of variables used when creating them. To illustrate this, consider the following example:

A = magic(3);
B = diag(A);
C = 20*B;
>> whos C
  Name      Size            Bytes  Class     Attributes
  C         3x1                24  double 
A = single(magic(3)); % A is converted to "single"
B = diag(A);
C = B*double(20);     % The stricter type, which in this case is "single", prevails
D = single(size(C));  % It is generally advised to cast to the desired type explicitly.
>> whos C
  Name      Size            Bytes  Class     Attributes
  C         3x1                12  single  

Thus, it may seem sufficient to cast/convert several initial variables to have the change permeate throughout the code - however this is discouraged (see Caveats & Pitfalls below).

Caveats & Pitfalls:

  1. Repeated conversions are discouraged due to the introduction of numeric noise (when casting from single to double) or loss of information (when casting from double to single, or between certain integer types), e.g. :

    double(single(1.2)) == double(1.2)   
    ans =

    This can be mitigated somewhat using typecast. See also Be aware of floating point inaccuracy.

  2. Relying solely on implicit data-typing (i.e. what MATLAB guesses the type of the output of a computation should be) is discouraged due to several undesired effects that might arise:

    • Loss of information: when a double result is expected, but a careless combination of single and double operands yields single precision.

    • Unexpectedly high memory consumption: when a single result is expected but a careless computation results in a double output.

    • Unnecessary overhead when working with GPUs: when mixing gpuArray types (i.e. variables stored in VRAM) with non-gpuArray variables (i.e. those usually stored in RAM) the data will have to be transferred one way or the other before the computation can be performed. This operation takes time, and can be very noticeable in repetative computations.

    • Errors when mixing floating-point types with integer types: functions like mtimes (*) are not defined for mixed inputs of integer and floating point types - and will error. Functions like times (.*) are not defined at all for integer-type inputs - and will again error.

      >> ones(3,3,'int32')*ones(3,3,'int32')
      Error using  * 
      MTIMES is not fully supported for integer classes. At least one input must be scalar.
      >> ones(3,3,'int32').*ones(3,3,'double')
      Error using  .* 
      Integers can only be combined with integers of the same class, or scalar doubles.

    For better code readability and reduced risk of unwanted types, a defensive approach is advised, where variables are explicitly cast to the desired type.

See Also: