Home > Enterprise >  Write binary file to disk super fast in MEX
Write binary file to disk super fast in MEX

Time:11-30

I need to write a large array of data to disk as fast as possible. From MATLAB I can do that with fwrite:

function writeBinaryFileMatlab(data)
    fid = fopen('file_matlab.bin', 'w');
    fwrite(fid, data, class(data));
    fclose(fid);
end

Now I have to do the same, but from a MEX file called by MATLAB. So I setup a MEX function that can write to file using either fstream or fopen (Inspired by the results of enter image description here

New compiler log:

Found installed compiler 'Microsoft Visual C   2017'.
Set PATH = C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\bin\HostX64\x64\;C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE\VC\vcpackages;C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\IDE;C:\Program Files\Microsoft Visual Studio\2022\Community\Common7\Tools;C:\Program Files (x86)\Windows Kits\10\\Bin\10.0.19041.0\x64;C:\Program Files (x86)\Windows Kits\10\\Bin\10.0.19041.0\x86;C:\Program Files (x86)\Windows Kits\10\\Bin\x64;C:\Program Files (x86)\Windows Kits\10\\Bin\x86;;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2\libnvvp;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\Microsoft Windows Performance Toolkit\;C:\PROGRA~1\MATLAB\R2020a\runtime\win64;C:\PROGRA~1\MATLAB\R2020a\bin;C:\Program Files\MATLAB\R2020a\runtime\win64;C:\Program Files\MATLAB\R2020a\bin;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Program Files\dotnet\;C:\Program Files\NVIDIA Corporation\Nsight Compute 2020.3.1\;C:\Users\rwaasdorp1\AppData\Local\Programs\Python\Python39;C:\Users\rwaasdorp1\AppData\Local\Programs\Microsoft VS Code;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2\bin\\..\extras\CUPTI\lib64;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2\bin;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2\libnvvp;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\WINDOWS\System32\OpenSSH\;C:\Program Files\Microsoft Windows Performance Toolkit\;C:\Program Files\MATLAB\R2020a\runtime\win64;C:\Program Files\MATLAB\R2020a\bin;C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;C:\Program Files\dotnet\;C:\Program Files\NVIDIA Corporation\Nsight Compute 2020.3.1\;C:\Users\rwaasdorp1\AppData\Local\Programs\Python\Python39;C:\Users\rwaasdorp1\AppData\Local\Programs\Microsoft VS Code;C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v11.2\bin\\..\extras\CUPTI\lib64;C:\Program Files (x86)\Common Files\Oracle\Java\javapath;C:\Program Files\NVID
Set INCLUDE = C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\atlmfc\include;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\ucrt;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\shared;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\um;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\winrt;C:\Program Files\MATLAB\R2020a\extern\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\include;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\atlmfc\include;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\ucrt;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\shared;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\um;C:\Program Files (x86)\Windows Kits\10\\include\10.0.19041.0\winrt;C:\Program Files\MATLAB\R2020a\extern\include;
Set LIB = C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\lib\x64;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\atlmfc\lib\x64;C:\Program Files (x86)\Windows Kits\10\\Lib\10.0.19041.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\um\x64;C:\Program Files\MATLAB\R2020a\lib\win64;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\lib\x64;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\atlmfc\lib\x64;C:\Program Files (x86)\Windows Kits\10\\Lib\10.0.19041.0\ucrt\x64;C:\Program Files (x86)\Windows Kits\10\\lib\10.0.19041.0\um\x64;C:\Program Files\MATLAB\R2020a\lib\win64;
Set LIBPATH = C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\lib\x64;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\atlmfc\lib\x64;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\lib\x64;C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705\atlmfc\lib\x64;
Options file details
-------------------------------------------------------------------
    Compiler location: C:\Program Files\Microsoft Visual Studio\2022\Community\
    Options file: C:\Users\rwaasdorp1\AppData\Roaming\MathWorks\MATLAB\R2020a\mex_C  _win64.xml
    CMDLINE200 : link /nologo /manifest  /DLL  /EXPORT:mexFunction /EXPORT:mexfilerequiredapiversion C:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\main.obj C:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\saveFunctions.obj C:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\cpp_mexapi_version.obj  /LIBPATH:"C:\Program Files\MATLAB\R2020a\extern\lib\win64\microsoft" libmx.lib libmex.lib libmat.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libMatlabDataArray.lib libMatlabEngine.lib /out:"C:\mypath\saveBinaryDataMex\saveBinData.mexw64"
    CMDLINE250 : mt -outputresource:"C:\mypath\saveBinaryDataMex\saveBinData.mexw64";2 -manifest "C:\mypath\saveBinaryDataMex\saveBinData.mexw64.manifest"
    CMDLINE300 : del "C:\mypath\saveBinaryDataMex\saveBinData.exp" "C:\mypath\saveBinaryDataMex\saveBinData.lib" "C:\mypath\saveBinaryDataMex\saveBinData.mexw64.manifest" "C:\mypath\saveBinaryDataMex\saveBinData.ilk"
    COMPILER : cl
    COMPFLAGS : /Zp8 /GR /W3 /EHs /nologo /MD
    COMPDEFINES : /DUSE_WINDOWS  /DMX_COMPAT_64  /DMATLAB_MEXCMD_RELEASE=R2018a  /DUSE_MEX_CMD   /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_SECURE_SCL=0   /DMATLAB_MEX_FILE
    MATLABMEX :  /DMATLAB_MEX_FILE
    OPTIMFLAGS : /O2 /Oy- /DNDEBUG
    INCLUDE : -I"include"  -I"C:\Program Files\MATLAB\R2020a\extern\include" -I"C:\Program Files\MATLAB\R2020a\simulink\include"
    DEBUGFLAGS : /Z7
    LINKER : link
    LINKFLAGS : /nologo /manifest 
    LINKTYPE : /DLL
    LINKEXPORT : /EXPORT:mexFunction
    LINKEXPORTVER : /EXPORT:mexFunction /EXPORT:mexfilerequiredapiversion
    LINKLIBS : /LIBPATH:"C:\Program Files\MATLAB\R2020a\extern\lib\win64\microsoft" libmx.lib libmex.lib libmat.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libMatlabDataArray.lib libMatlabEngine.lib
    LINKDEBUGFLAGS : /debug /PDB:"C:\mypath\saveBinaryDataMex\saveBinData.mexw64.pdb"
    LINKOPTIMFLAGS : 
    OBJEXT : .obj
    LDEXT : .mexw64
    SETENV : set COMPILER=cl
                set COMPFLAGS=/c /Zp8 /GR /W3 /EHs /nologo /MD /DUSE_WINDOWS  /DMX_COMPAT_64  /DMATLAB_MEXCMD_RELEASE=R2018a  /DUSE_MEX_CMD   /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_SECURE_SCL=0   /DMATLAB_MEX_FILE  /DMATLAB_MEX_FILE
                set OPTIMFLAGS=/O2 /Oy- /DNDEBUG
                set DEBUGFLAGS=/Z7
                set LINKER=link
                set LINKFLAGS=/nologo /manifest  /export:%ENTRYPOINT% /DLL /LIBPATH:"C:\Program Files\MATLAB\R2020a\extern\lib\win64\microsoft" libmx.lib libmex.lib libmat.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libMatlabDataArray.lib libMatlabEngine.lib /EXPORT:mexFunction
                set LINKDEBUGFLAGS=/debug /PDB:"%OUTDIR%%MEX_NAME%.mexw64.pdb"
                set NAME_OUTPUT=/out:"%OUTDIR%%MEX_NAME%%MEX_EXT%"
    VCROOT : C:\Program Files\Microsoft Visual Studio\2022\Community
    SDKROOT : C:\Program Files (x86)\Windows Kits\10\
    VSINSTALLDIR : C:\Program Files\Microsoft Visual Studio\2022\Community
    VCINSTALLDIR : C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.30.30705
    VCVARSALLDIR : C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Auxiliary\Build
    KITSROOT : C:\Program Files (x86)\Windows Kits\10\
    SDKVERSION : 10.0.19041.0
    MATLABROOT : C:\Program Files\MATLAB\R2020a
    ARCH : win64
    SRC : "C:\mypath\saveBinaryDataMex\src\main.cpp";"C:\mypath\saveBinaryDataMex\src\saveFunctions.cpp";"C:\Program Files\MATLAB\R2020a\extern\version\cpp_mexapi_version.cpp"
    OBJ : C:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\main.obj;C:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\saveFunctions.obj;C:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\cpp_mexapi_version.obj
    OBJS : C:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\main.obj C:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\saveFunctions.obj C:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\cpp_mexapi_version.obj 
    SRCROOT : C:\mypath\saveBinaryDataMex\src\main
    DEF : C:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\saveBinData.def
    EXP : "C:\mypath\saveBinaryDataMex\saveBinData.exp"
    LIB : "C:\mypath\saveBinaryDataMex\saveBinData.lib"
    EXE : "C:\mypath\saveBinaryDataMex\saveBinData.mexw64"
    ILK : "C:\mypath\saveBinaryDataMex\saveBinData.ilk"
    MANIFEST : "C:\mypath\saveBinaryDataMex\saveBinData.mexw64.manifest"
    TEMPNAME : C:\mypath\saveBinaryDataMex\saveBinData
    EXEDIR : C:\mypath\saveBinaryDataMex\
    EXENAME : saveBinData
    OPTIM : /O2 /Oy- /DNDEBUG
    LINKOPTIM : 
    CMDLINE100_0 : cl /c /Zp8 /GR /W3 /EHs /nologo /MD /O2 /Oy- /DNDEBUG /DUSE_WINDOWS  /DMX_COMPAT_64  /DMATLAB_MEXCMD_RELEASE=R2018a  /DUSE_MEX_CMD   /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_SECURE_SCL=0   /DMATLAB_MEX_FILE -I"include"  -I"C:\Program Files\MATLAB\R2020a\extern\include" -I"C:\Program Files\MATLAB\R2020a\simulink\include" "C:\mypath\saveBinaryDataMex\src\main.cpp" /FoC:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\main.obj
    CMDLINE100_1 : cl /c /Zp8 /GR /W3 /EHs /nologo /MD /O2 /Oy- /DNDEBUG /DUSE_WINDOWS  /DMX_COMPAT_64  /DMATLAB_MEXCMD_RELEASE=R2018a  /DUSE_MEX_CMD   /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_SECURE_SCL=0   /DMATLAB_MEX_FILE -I"include"  -I"C:\Program Files\MATLAB\R2020a\extern\include" -I"C:\Program Files\MATLAB\R2020a\simulink\include" "C:\mypath\saveBinaryDataMex\src\saveFunctions.cpp" /FoC:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\saveFunctions.obj
    CMDLINE100_2 : cl /c /Zp8 /GR /W3 /EHs /nologo /MD /O2 /Oy- /DNDEBUG /DUSE_WINDOWS  /DMX_COMPAT_64  /DMATLAB_MEXCMD_RELEASE=R2018a  /DUSE_MEX_CMD   /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_SECURE_SCL=0   /DMATLAB_MEX_FILE -I"include"  -I"C:\Program Files\MATLAB\R2020a\extern\include" -I"C:\Program Files\MATLAB\R2020a\simulink\include" "C:\Program Files\MATLAB\R2020a\extern\version\cpp_mexapi_version.cpp" /FoC:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\cpp_mexapi_version.obj
-------------------------------------------------------------------
Building with 'Microsoft Visual C   2017'.
cl /c /Zp8 /GR /W3 /EHs /nologo /MD /O2 /Oy- /DNDEBUG /DUSE_WINDOWS  /DMX_COMPAT_64  /DMATLAB_MEXCMD_RELEASE=R2018a  /DUSE_MEX_CMD   /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_SECURE_SCL=0   /DMATLAB_MEX_FILE -I"include"  -I"C:\Program Files\MATLAB\R2020a\extern\include" -I"C:\Program Files\MATLAB\R2020a\simulink\include" "C:\mypath\saveBinaryDataMex\src\main.cpp" /FoC:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\main.obj
main.cpp

cl /c /Zp8 /GR /W3 /EHs /nologo /MD /O2 /Oy- /DNDEBUG /DUSE_WINDOWS  /DMX_COMPAT_64  /DMATLAB_MEXCMD_RELEASE=R2018a  /DUSE_MEX_CMD   /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_SECURE_SCL=0   /DMATLAB_MEX_FILE -I"include"  -I"C:\Program Files\MATLAB\R2020a\extern\include" -I"C:\Program Files\MATLAB\R2020a\simulink\include" "C:\mypath\saveBinaryDataMex\src\saveFunctions.cpp" /FoC:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\saveFunctions.obj
saveFunctions.cpp
C:\mypath\saveBinaryDataMex\src\saveFunctions.cpp(26): warning C4267: 'argument': conversion from 'size_t' to 'DWORD', possible loss of data

cl /c /Zp8 /GR /W3 /EHs /nologo /MD /O2 /Oy- /DNDEBUG /DUSE_WINDOWS  /DMX_COMPAT_64  /DMATLAB_MEXCMD_RELEASE=R2018a  /DUSE_MEX_CMD   /D_CRT_SECURE_NO_DEPRECATE /D_SCL_SECURE_NO_DEPRECATE /D_SECURE_SCL=0   /DMATLAB_MEX_FILE -I"include"  -I"C:\Program Files\MATLAB\R2020a\extern\include" -I"C:\Program Files\MATLAB\R2020a\simulink\include" "C:\Program Files\MATLAB\R2020a\extern\version\cpp_mexapi_version.cpp" /FoC:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\cpp_mexapi_version.obj
cpp_mexapi_version.cpp

link /nologo /manifest  /DLL  /EXPORT:mexFunction /EXPORT:mexfilerequiredapiversion C:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\main.obj C:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\saveFunctions.obj C:\Users\RWAASD~1\AppData\Local\Temp\mex_29341090340414_4136\cpp_mexapi_version.obj  /LIBPATH:"C:\Program Files\MATLAB\R2020a\extern\lib\win64\microsoft" libmx.lib libmex.lib libmat.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib libMatlabDataArray.lib libMatlabEngine.lib /out:"C:\mypath\saveBinaryDataMex\saveBinData.mexw64"
   Creating library C:\mypath\saveBinaryDataMex\saveBinData.lib and object C:\mypath\saveBinaryDataMex\saveBinData.exp

mt -outputresource:"C:\mypath\saveBinaryDataMex\saveBinData.mexw64";2 -manifest "C:\mypath\saveBinaryDataMex\saveBinData.mexw64.manifest"
Microsoft (R) Manifest Tool

Copyright (c) Microsoft Corporation. 

All rights reserved.


del "C:\mypath\saveBinaryDataMex\saveBinData.exp" "C:\mypath\saveBinaryDataMex\saveBinData.lib" "C:\mypath\saveBinaryDataMex\saveBinData.mexw64.manifest" "C:\mypath\saveBinaryDataMex\saveBinData.ilk"
MEX completed successfully.

CodePudding user response:

[This is a partial answer only, unfortunately.]

This is a Windows problem. I tried reproducing your results on macOS, and found a different, interesting behavior. I modified your code to distinguish between the C fwrite and the C std::fwrite, and I added code to write using the lower-level Posix write.

This is the C code:

#include "mex.h"
#include <stdio.h>
#include <cstdio>
#include <fcntl.h>
#include <unistd.h>

void writeBinFile_c(int16_t *data, std::size_t size)
{
    ::FILE *fID = ::fopen("file_c.bin", "wb");
    ::fwrite(data, sizeof(int16_t), size, fID);
    ::fclose(fID);
}

void writeBinFile_std(int16_t *data, std::size_t size)
{
    std::FILE *fID = std::fopen("file_std.bin", "wb");
    std::fwrite(data, sizeof(int16_t), size, fID);
    std::fclose(fID);
}

void writeBinFile_unix(int16_t *data, std::size_t size)
{
    int fID = open("file_unix.bin", O_CREAT|O_WRONLY|O_TRUNC);
    ::write(fID, data, sizeof(int16_t) * size);
    ::close(fID);
}

void mexFunction(int nlhs, mxArray *plhs[],
                 int nrhs, const mxArray *prhs[])
{
    const mxArray *mxPtr = prhs[0];
    std::size_t nelems = mxGetNumberOfElements(mxPtr);
    int16_t *ptr = (int16_t *)mxGetData(mxPtr);
    double mode = -1;
    if (nrhs > 1) {
      mode = mxGetScalar(prhs[1]);
    }
    if (mode == 0) {
       writeBinFile_c(ptr, nelems);
    } else if (mode == 1) {
       writeBinFile_std(ptr, nelems);
    } else if (mode == 2) {
       writeBinFile_unix(ptr, nelems);
    } else {
       mexErrMsgTxt("Wrong mode!");
    }
}

This is the MATLAB code:

mex -R2018a -Iinclude CXXFLAGS="$CXXFLAGS -O3" writefast.cpp

N = 10;
sizeMB = zeros(1,N);
t_matlab = zeros(1,N);
t_fwrite_c = zeros(1,N);
t_fwrite_std = zeros(1,N);
t_unix = zeros(1,N);
for k = 1:10
    sizeBytes = 2^k * 1024 * 1024;
    fprintf('Generating data of size %i MB\n', sizeBytes / 2^20)
    M = sizeBytes / 2; % 2 bytes for an int16
    sizeMB(k) = sizeBytes / 2^20;
    data = int16(rand(M, 1) * 100);

    fprintf('TESTING: matlab\n')
    t_matlab(k) = timeit(@() writeBinaryFileMatlab(data));

    fprintf('TESTING: ::fwrite\n')
    t_fwrite_c(k) = timeit(@() writefast(data, 0), 0);

    fprintf('TESTING: std::fwrite\n')
    t_fwrite_std(k) = timeit(@() writefast(data, 1), 0);

    fprintf('TESTING: Unix write\n')
    t_unix(k) = timeit(@() writefast(data, 1), 0);
end

% and plot result
figure
plot((sizeMB), t_matlab)
hold on
plot((sizeMB), t_fwrite_c)
plot((sizeMB), t_fwrite_std)
plot((sizeMB), t_unix)
legend('Matlab', 'C std lib', 'C   Std lib', 'Unix')
xticks(sizeMB)
set(gca,'xscale','log','yscale','log')

function writeBinaryFileMatlab(data)
    fid = fopen('file_matlab.bin', 'w');
    fwrite(fid, data, class(data));
    fclose(fid);
end

These are the outputs for two runs:

run 1 run2

Note how timings are consistent up to 64 MB, and then diverge. At 128 MB and up, the times are long enough for timeit to run the tool only once in the inner loop, and so you see the median time for individual runs, without averaging over multiple runs as it does at 64 MB and below. So for 128 MB and above we see the times flipping between two different times, which is maybe an effect of caching. But in different runs, it's different methods that are slower or faster, and so it is clear to me that they all do the same.

So, on macOS, there is no difference between MATLAB's fwrite and the C library fwrite. What you saw must be a Windows issue.

And I am pretty certain this has to do with caching, because:

  • enter image description here

  • Related