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
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:
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: