1st Edition

Accelerating MATLAB Performance 1001 tips to speed up MATLAB programs

By Yair M. Altman Copyright 2015
    792 Pages 31 Color & 228 B/W Illustrations
    by Chapman & Hall

    The MATLAB® programming environment is often perceived as a platform suitable for prototyping and modeling but not for "serious" applications. One of the main complaints is that MATLAB is just too slow.

    Accelerating MATLAB Performance aims to correct this perception by describing multiple ways to greatly improve MATLAB program speed. Packed with thousands of helpful tips, it leaves no stone unturned, discussing every aspect of MATLAB.

    Ideal for novices and professionals alike, the book describes MATLAB performance in a scale and depth never before published. It takes a comprehensive approach to MATLAB performance, illustrating numerous ways to attain the desired speedup.

    The book covers MATLAB, CPU, and memory profiling and discusses various tradeoffs in performance tuning. It describes both the application of standard industry techniques in MATLAB, as well as methods that are specific to MATLAB such as using different data types or built-in functions.

    The book covers MATLAB vectorization, parallelization (implicit and explicit), optimization, memory management, chunking, and caching. It explains MATLAB’s memory model and details how it can be leveraged. It describes the use of GPU, MEX, FPGA, and other forms of compiled code, as well as techniques for speeding up deployed applications. It details specific tips for MATLAB GUI, graphics, and I/O. It also reviews a wide variety of utilities, libraries, and toolboxes that can help to improve performance.

    Sufficient information is provided to allow readers to immediately apply the suggestions to their own MATLAB programs. Extensive references are also included to allow those who wish to expand the treatment of a particular topic to do so easily.

    Supported by an active website, and numerous code examples, the book will help readers rapidly attain significant reductions in development costs and program run times.

    1. Introduction to Performance Tuning
    1.1 Why Should We Bother?
    1.2 When to Performance-Tune and When Not to Bother
    1.3 The Iterative Performance Tuning Cycle
    1.3.1 Pareto’s Principle and the Law of Diminishing Returns
    1.3.2 When to Stop Tuning
    1.3.3 Periodic Performance Maintenance
    1.4What to Tune
    1.5Performance Tuning Pitfalls
    1.5.1 When to Tune
    1.5.2 Performance Goals
    1.5.3 Profiling
    1.5.4 Optimization
    1.6 Performance Tuning Tradeoffs
    1.7 Vertical versus Horizontal Scaling
    1.8 Perceived versus Actual Performance
    1.8.1 Presenting Continuous Feedback for Ongoing Tasks
    1.8.2 Placing the User in Control
    1.8.3 Enabling User Interaction during Background Processing
    1.8.4 Streaming Data as it Becomes Available
    1.8.5 Streamlining the Application
    1.8.6 Reducing the Run-Time Variability
    1.8.7 Performance and Real Time

    2. Profiling MATLAB® Performance
    2.1 The MATLAB Profiler
    2.1.1 The Detailed Profiling Report
    2.1.2 A Sample Profiling Session
    2.1.3 Programmatic Access to Profiling Data
    2.1.4 Function-Call History Timeline
    2.1.5 CPU versus Wall-Clock Profiling
    2.1.6 Profiling Techniques
    2.1.6.1 Relative versus Absolute Run Times
    2.1.6.2 Ensuring Profiling Consistency
    2.1.6.3 Ensuring Compatibility with Real-World Conditions
    2.1.6.4 Profiling GUI and I/O
    2.1.6.5 Code Coverage
    2.1.7 Profiling Limitations
    2.1.8 Profiling and MATLAB’s JIT
    2.2 tic, toc and Relatives
    2.2.1 The Built-In tic, toc Functions
    2.2.2 Comparison between the Profiler and tic, toc
    2.2.3 Related Tools
    2.3 Timed Log Files and Printouts
    2.4 Non-MATLAB Tools

    3. Standard Performance-Tuning Techniques
    3.1 Loop Optimization
    3.1.1 Move Loop-Invariant Code Out of the Loop
    3.1.1.1 A Simple Example
    3.1.1.2 I/O and Memory-Related Invariants
    3.1.1.3 Subexpression Hoisting
    3.1.1.4 Loop Conditionals
    3.1.1.5 Invoked Functions
    3.1.2 Minimize Function Call Overheads
    3.1.3 Employ Early Bail-Outs
    3.1.4 Simplify Loop Contents
    3.1.5 Unroll Simple Loops
    3.1.6 Optimize Nested Loops
    3.1.7 Switch the Order of Nested Loops
    3.1.8 Minimize Dereferencing
    3.1.9 Postpone I/O and Graphics Until the Loop Ends
    3.1.10 Merge or Split Loops
    3.1.11 Loop Over the Shorter Dimension
    3.1.12 Run Loops Backwards
    3.1.13 Partially Optimize a Loop
    3.1.14 Use the Loop Index Rather than Counters
    3.1.15 MATLAB’s JIT
    3.2 Data Caching
    3.2.1 Read-Only Caches
    3.2.2 Common Subexpression Elimination
    3.2.3 Persistent Caches
    3.2.3.1 In-Memory Persistence
    3.2.3.2 Non-Memory Persistence
    3.2.4 Writable Caches
    3.2.4.1 Initializing Cache Data
    3.2.4.2 Memoization
    3.2.4.3 Multilayered (Offline) Cache
    3.2.5 A Real-Life Example: Writable Cache
    3.2.6 Optimizing Cache Fetch Time
    3.3 Smart Checks Bypass
    3.4 Exception Handling
    3.5 Improving Externally Connected Systems
    3.5.1 Database
    3.5.1.1 Design
    3.5.1.2 Storage
    3.5.1.3 Indexing
    3.5.1.4 Driver and Connection
    3.5.1.5 SQL Queries
    3.5.1.6 Data Updates
    3.5.2 File System and Network
    3.5.3 Computer Hardware
    3.6 Processing Smaller Data Subsets
    3.6.1 Reading from a Database
    3.6.2 Reading from a Data File
    3.6.3 Processing Data
    3.7 Interrupting Long-Running Tasks
    3.8 Latency versus Throughput
    3.8.1 Lazy Evaluation
    3.8.2 Prefetching
    3.9 Data Analysis
    3.9.1 Preprocessing the Data
    3.9.2 Controlling the Target Accuracy
    3.9.3 Reducing Problem Complexity
    3.10 Other Techniques
    3.10.1 Coding
    3.10.1.1 Recursion
    3.10.1.2 Using Known Computational Identities
    3.10.1.3 Remove Unnecessary Computations ("Dead-Code" Elimination)
    3.10.1.4 Optimize Conditional Constructs
    3.10.1.5 Use Short-Circuit Conditionals (Smartly!)
    3.10.1.6 Multiply Rather than Divide (or Not)
    3.10.2 Data
    3.10.2.1 Optimize the Processed Data
    3.10.2.2 Select Appropriate Data Structures
    3.10.2.3 Utilize I/O Data Compression
    3.10.3 General
    3.10.3.1 Reduce System Interferences
    3.10.3.2 Self-Tuning
    3.10.3.3 Jon Bentley’s Rules

    4. MATLAB®-Specific Techniques
    4.1 Effects of Using Different Data Types
    4.1.1 Numeric versus Nonnumeric Data Types
    4.1.2 Nondouble and Multidimensional Arrays
    4.1.3 Sparse Data
    4.1.4 Modifying Data Type in Run Time
    4.1.5 Concatenating Cell Arrays
    4.1.6 Datasets, Tables, and Categorical Arrays
    4.1.7 Additional Aspects
    4.2 Characters and Strings
    4.2.1 MATLAB’s Character/Number Duality
    4.2.2 Search and Replace
    4.2.3 Converting Numbers to Strings (and Back)
    4.2.4 String Comparison
    4.2.5 Additional Aspects
    4.2.5.1 Deblanking
    4.2.5.2 Concatenating Strings
    4.2.5.3 Converting Java Strings into MATLAB
    4.2.5.4 Internationalization
    4.3 Using Internal Helper Functions
    4.3.1 A Sample Debugging Session
    4.4 Date and Time Functions
    4.5 Numeric Processing
    4.5.1 Using inf and NaN
    4.5.2 Matrix Operations
    4.5.3 Real versus Complex Math
    4.5.4 Gradient
    4.5.5 Optimization
    4.5.6 Fast Fourier Transform
    4.5.7 Updating the Math Libraries
    4.5.8 Random Numbers
    4.6 Functional Programming
    4.6.1 Invoking Functions
    4.6.1.1 Scripts versus Functions
    4.6.1.2 Function Types
    4.6.1.3 Input and Output Parameters
    4.6.1.4 Switchyard Functions Dispatch
    4.6.2 onCleanup
    4.6.3 Conditional Constructs
    4.6.4 Smaller Functions and M-files
    4.6.5 Effective Use of the MATLAB Path
    4.6.6 Overloaded Built-In MATLAB Functions
    4.7 Object-Oriented MATLAB
    4.7.1 Object Creation
    4.7.2 Accessing Properties
    4.7.3 Invoking Methods
    4.7.4 Using System Objects
    4.8 MATLAB Start-Up
    4.8.1 The MATLAB Startup Accelerator
    4.8.2 Starting MATLAB in Batch Mode
    4.8.3 Slow MATLAB Start-Up
    4.8.4 Profiling MATLAB Start-Up
    4.8.5 Java Start-Up
    4.9 Additional Techniques
    4.9.1 Reduce the Number of Workspace Variables
    4.9.2 Loop Over the Smaller Data Set
    4.9.3 Referencing Dynamic Struct Fields and Object Properties
    4.9.4 Use Warning with a Specific Message ID
    4.9.5 Prefer num2cell Rather than mat2cell
    4.9.6 Avoid Using containers.Map
    4.9.7 Use the Latest MATLAB Release and Patches
    4.9.8 Use is* Functions Where Available
    4.9.9 Specify the Item Type When Using ishghandle or exist
    4.9.10 Use Problem-Specific Tools
    4.9.11 Symbolic Arithmetic
    4.9.12 Simulink
    4.9.13 Mac OS
    4.9.14 Additional Ideas

    5. Implicit Parallelization (Vectorization and Indexing)
    5.1 Introduction to MATLAB Vectorization
    5.1.1 So What Exactly is MATLAB Vectorization?
    5.1.2 Indexing Techniques
    5.1.3 Logical Indexing
    5.2 Built-In Vectorization Functions
    5.2.1 Functions for Common Indexing Usage Patterns
    5.2.2 Functions That Create Arrays
    5.2.3 Functions That Accept Vectorized Data
    5.2.3.1 reshape
    5.2.4 Functions That Apply Another Function in a Vectorized Manner
    5.2.4.1 arrayfun, cellfun, spfun, and structfun
    5.2.4.2 bsxfun
    5.2.5 Set-Based Functions
    5.3 Simple Vectorization Examples
    5.3.1 Trivial Transformations
    5.3.2 Partial Data Summation
    5.3.3 Thresholding
    5.3.4 Cumulative Sum
    5.3.5 Data Binning
    5.3.6 Using meshgrid and bsxfun
    5.3.7 A meshgrid Variant
    5.3.8 Euclidean Distances
    5.3.9 Range Search
    5.3.10 Matrix Computations
    5.4 Repetitive Data
    5.4.1 A Simple Example
    5.4.2 Using repmat Replacements
    5.4.3 Repetitions of Internal Elements
    5.5 Multidimensional Data
    5.6 Real-Life Example: Synthetic Aperture Radar Matched Filter
    5.6.1 Naïve Approach
    5.6.2 Using Vectorization
    5.7 Effective Use of MATLAB Vectorization
    5.7.1 Vectorization Is Not Always Faster
    5.7.2 Applying Smart Indexing
    5.7.3 Breaking a Problem into Simpler Vectorizable Subproblems
    5.7.4 Using Vectorization as Replacement for Iterative Data Updates
    5.7.5 Minimizing Temporary Data Allocations
    5.7.6 Preprocessing Inputs, Rather Than Postprocessing the Output
    5.7.7 Interdependent Loop Iterations
    5.7.8 Reducing Loop Complexity
    5.7.9 Reducing Processing Complexity
    5.7.10 Nested Loops
    5.7.11 Analyzing Loop Pattern to Extract a Vectorization Rule
    5.7.12 Vectorizing Structure Elements
    5.7.13 Limitations of Internal Parallelization
    5.7.14 Using MATLAB’s Character/Number Duality
    5.7.15 Acklam’s Vectorization Guide and Toolbox
    5.7.16 Using Linear Algebra to Avoid Looping Over Matrix Indexes
    5.7.17 Intersection of Curves: Reader Exercise

    6. Explicit Parallelization Using MathWorks Toolboxes
    6.1 The Parallel Computing Toolbox — CPUs
    6.1.1 Using parfor-Loops
    6.1.2 Using spmd
    6.1.3 Distributed and Codistributed Arrays
    6.1.4 Interactive Parallel Development with pmode
    6.1.5 Profiling Parallel Blocks
    6.1.6 Running Example: Using parfor Loops
    6.1.7 Running Example: Using spmd
    6.2 The Parallel Computing Toolbox — GPUs
    6.2.1 Introduction to General-Purpose GPU Computing
    6.2.2 Parallel Computing with GPU Arrays
    6.2.3 Running Example: Using GPU Arrays
    6.2.4 Running Example: Using Multiple GPUs with spmd Construct
    6.2.5 Executing CUDA Kernels from MATLAB
    6.2.6 Running Example: Using CUDA Kernels
    6.2.7 Programming GPU Using MATLAB MEX
    6.2.8 Accessing GPUs from within Parallel Blocks
    6.3 The MATLAB Distributed Computing Server
    6.3.1 Using MDCS
    6.3.2 Parallel Jobs Overview
    6.3.3 Setting Up a Scheduler Interface
    6.3.4 Programming Independent Jobs
    6.3.5 Programming Communicating Jobs
    6.3.6 Using Batch Processing on a Cluster
    6.3.7 Running Example: Using Communicating Jobs on a Cluster
    6.4 Techniques for Effective Parallelization in MATLAB
    6.4.1 General Performance Tips
    6.4.2 Performance Tips for Parallel CPU Programming
    6.4.3 Performance Tips for Parallel GPU Programming

    7. Explicit Parallelization by Other Means
    7.1 GPU Acceleration Using Jacket
    7.1.1 Key Ideas of Jacket Design
    7.1.2 Jacket Interface to MATLAB
    7.1.3 Using Parallel gfor Loops
    7.1.4 Compiling M-Code to a CUDA Kernel with Gcompile
    7.1.5 Multi-GPU Support
    7.1.6 Running Example: Using Parallel gfor-Loop
    7.1.7 Running Example: Using gcompile
    7.1.8 Running Example: Using spmd and Multi-GPU Support
    7.2 Alternative/Related Technologies
    7.2.1 Using GPUmat
    7.2.2 Multicore Library for Parallel Processing on Multiple Cores
    7.2.3 Using ArrayFire Library via MEX Interface
    7.2.4 Additional Alternatives
    7.3 Multithreading
    7.3.1 Using POSIX Threads
    7.3.2 Using OpenMP
    7.3.3 Using Java Threads
    7.3.4 Using .Net Threads
    7.3.5 Using MATLAB Timers
    7.4 Spawning External Processes

    8. Using Compiled Code
    8.1 Using MEX Code
    8.1.1 Introduction
    8.1.2 Our First MEX Function
    8.1.2.1 Setting Up the Compiler
    8.1.2.2 The Basic Format of a MEX File
    8.1.2.3 "Hello, World"
    8.1.3 MEX Function Inputs and Outputs
    8.1.4 Accessing MATLAB Data
    8.1.4.1 mxArray
    8.1.4.2 Standard MEX API for MATLAB Data Access
    8.1.5 A Usage Example
    8.1.6 Memory Management
    8.1.7 Additional Aspects
    8.1.7.1 Profiling MEX Code
    8.1.7.2 Calling MATLAB Functions
    8.1.7.3 Calling Functions in External Libraries
    8.1.7.4 Miscellaneous Aspects
    8.2 Using the MATLAB Coder Toolbox
    8.2.1 Code Adaptation
    8.2.2 A Simple Example: Euclidean Distances Algorithm
    8.2.3 A More Realistic Example: Dijkstra’s Shortest-Path Algorithm
    8.2.3.1 Compatibility Check
    8.2.3.2 Converting Nested Functions into Sub-Functions
    8.2.3.3 Converting Cell Arrays to Numeric Arrays
    8.2.3.4 Bypassing Unsupported MATLAB Calls
    8.2.3.5 Compiling the Code
    8.2.3.6 Using the Compiled Code
    8.2.4 Configuring the Coder for Maximal Performance
    8.3 Porting MATLAB Algorithms to FPGA
    8.3.1 Algorithm Adaptation
    8.3.2 HDL Workflow
    8.3.3 Run-Time Measurements
    8.4 Deployed (Compiled) MATLAB Programs
    8.5 Using External Libraries
    8.5.1 Introduction
    8.5.2 Java
    8.5.3 NAG: Numerical Algorithms Group
    8.5.4 MATLAB Toolbox
    8.5.5 MCT: Multi-Precision Computing Toolbox
    8.5.6 Additional Libraries
    8.5.6.1 LightSpeed
    8.5.6.2 Spiral
    8.5.6.3 Additional Toolboxes

    9. Memory-Related Techniques
    9.1 Why Memory Affects Performance
    9.2 Profiling Memory Usage
    9.2.1 Workspace Browser
    9.2.2 whos Function
    9.2.3 memory Function
    9.2.4 feature memstats and feature dumpmem
    9.2.5 feature mtic/mtoc
    9.2.6 Profiler’s Memory-Monitoring Feature
    9.2.7 Profiling Java Memory
    9.2.8 Using Third-Party Tools
    9.2.9 Using the Operating System’s Tools
    9.2.10 format debug
    9.3 MATLAB’s Memory Storage and Looping Order
    9.3.1 Memory Storage of MATLAB Array Data
    9.3.2 Loop Down Columns Rather Than Rows
    9.3.3 Effect of Subindexing
    9.4 Array Memory Allocation
    9.4.1 Dynamic Array Growth
    9.4.2 Effects of Incremental JIT Improvements
    9.4.3 Preallocate Large Data Arrays
    9.4.4 Preallocation Location within the Code
    9.4.5 Preallocating Nondouble Data
    9.4.6 Alternatives for Enlarging Arrays
    9.5 Minimizing Memory Allocations
    9.5.1 MATLAB’s Copy-on-Write Mechanism
    9.5.1.1 Regular Variable Copies
    9.5.1.2 Function Input Parameters
    9.5.2 In-Place Data Manipulations
    9.5.3 Reusing Variables (with Utmost Care)
    9.5.4 Clearing Unused Workspace Variables
    9.5.5 Global and Persistent Variables
    9.5.6 Scoping Rules and Nested Functions
    9.5.7 Passing Handle References (Not Data) to Functions
    9.5.8 Reducing Data Precision/Type
    9.5.9 Devectorizing Huge Data Operations
    9.5.10 Assign Anonymous Functions in Dedicated Wrapper Functions
    9.5.11 Represent Objects by Simpler Data Types
    9.6 Memory Packing
    9.7 Additional Recommendations
    9.7.1 MATLAB Variables
    9.7.2 Java Objects

    10. Graphics and GUI
    10.1 Initial Graphs Generation
    10.1.1 Reduce the Number of Plotting Elements
    10.1.1.1 Do Not Plot Hidden Elements
    10.1.1.2 Do Not Plot Overlapped Elements
    10.1.1.3 Use the Scatter Plot with More Than 100 Data Points
    10.1.1.4 Use NaN or Inf Data Values to Reduce the Number of Line Segments
    10.1.1.5 Use Only End-Points When Plotting Straight (Linear) Lines
    10.1.2 Use Simple or No Plot Markers
    10.1.3 Use Vectorized Data for Plotting
    10.1.4 Use Static Axes Properties
    10.1.5 Only Use Drawnow When You Are Finished Plotting
    10.1.6 Use Low-Level Rather Than High-Level Graphic Functions
    10.1.7 Generate Plots While the Figure Is Hidden
    10.1.8 Apply Data Reduction to Plotted Data to Fit the Display Area
    10.1.9 Reuse Plot Axes
    10.1.10 Avoid Using the Axes Function
    10.1.11 Use the Painters Figure Renderer with Fast Axes DrawMode
    10.1.12 Images
    10.1.12.1 Reduce Image File Size
    10.1.12.2 Use Integer Image Data
    10.1.12.3 Use Direct Color Mapping (Indexed Images)
    10.1.12.4 Cropping
    10.1.13 Patches and Volume Surfaces
    10.1.14 Colorbars
    10.1.15 Legends
    10.1.16 Reopen Presaved Figure and/or Plot Axes
    10.2 Updating Graphs and Images in Real Time
    10.2.1 Axes Update
    10.2.2 Plot and Image Update
    10.2.3 Legends and Colorbars
    10.2.4 Accessing Object Properties
    10.2.5 Listeners and Callbacks
    10.2.6 Trading Accuracy for Speed
    10.2.7 Avoid Update to the Same Value
    10.2.8 Cache Graphic Handles
    10.3 Figure Window Performance Aspects
    10.3.1 Use Hardware-Accelerated OpenGL Renderer and Functionality
    10.3.2 Set a Nondefault WVisual/XVisual Property Value
    10.3.3 Disable BackingStore
    10.3.4 Disable DoubleBuffer
    10.3.5 Set a Manual DitherMapMode on Old Platforms
    10.3.6 Reuse Figure Windows
    10.3.7 Sharing Data between GUI Callback Functions
    10.4 GUI Preparation and Responsiveness
    10.4.1 Creating the Initial GUI
    10.4.1.1 Create and Update GUI Components in Nonvisible Mode
    10.4.1.2 Reuse Existing Figure Windows and GUI Components
    10.4.1.3 Reduce the Number of Property Updates
    10.4.1.4 Prevent Unnecessary Callback Invocations
    10.4.1.5 Postpone Nongraphical Setup and Updates
    10.4.1.6 Make the GUI Simple to Use
    10.4.1.7 uitable Considerations
    10.4.2 Presenting User Feedback
    10.4.2.1 Psychology of User Feedback
    10.4.2.2 Feedback in MATLAB Applications
    10.4.2.3 Feedback in MATLAB Slider Controls
    10.4.2.4 Temporarily Disabling User Interaction
    10.4.2.5 Feedback for Long-Duration Tasks
    10.4.2.6 Feedback for High-Volatility Data
    10.4.2.7 Reducing Intermediate Updates
    10.4.3 Performing Asynchronous Actions
    10.4.3.1 Update GUI Selectively
    10.4.3.2 Reduce Callback Execution Time
    10.4.3.3 Prevent Callback Re-entrancy
    10.4.3.4 Disable Control Callbacks during Automated Updates
    10.4.3.5 Prefer Asynchronous Callbacks to Synchronous Polling
    10.4.3.6 Optimize Polling Performance
    10.4.3.7 Zoom and Pan
    10.4.3.8 Mouse Movement and Hover
    10.5 Avoiding Common Pitfalls
    10.5.1 Minimize Intentional Pauses
    10.5.2 Delete Unused Graphic Objects

    11. I/O Techniques
    11.1 Reducing the Amount of I/O
    11.2 Avoiding Repeated File Access
    11.3 Reading and Writing Files
    11.3.1 Text versus Binary Format
    11.3.2 Text File Pre-Processing
    11.3.3 Memory-Mapped Files
    11.3.4 Reading Files Efficiently
    11.3.5 Writing Files Efficiently
    11.4 Data Compression and the save Function
    11.5 Excel Files (and Microsoft Office Files in General)
    11.6 Image Files
    11.7 Using Java and C I/O
    11.8 Searching, Parsing, and Comparing Files
    11.8.1 Searching for Files
    11.8.2 Parsing and Scanning Files
    11.9 Additional Aspects
    11.9.1 Using p-Code
    11.9.2 Network I/O
    11.9.3 Miscellaneous

    Appendix A: Additional Resources
    Online Resources
    Books
    Performance-Related Official MATLAB Bugs
    Performance-Related Code Analyzer (MLint) Warnings

    Appendix B: Performance Tuning Checklist

    References

    Index

    Biography

    Yair M. Altman

    … a very interesting new book on MATLAB® performance … covering basic tools and an appropriate range of specific programming techniques. The book seems to take a whole-system approach … helping readers understand the big picture of how to get better performance.
    —Michelle Hirsch, Ph.D., Head of MATLAB® Product Management, The MathWorks Inc.