- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
I'm using ifort 2015 Update 4 to write some arrays to a disk, and the performance is too slow. If it matters, I set the default Integer size and default Real size to 8-byte. I figured, why don’t I write to a shared memory handle instead of directly to a disk file, and then the performance should be better. I have encountered two problems that I would like some advice.
After my code change, the top performance hit was WriteFile (Windows file writing, which I moved to a separate thread, given that I only have a cheap HDD) – great! However, the next performance hit is the function for_write_seq_xmit. So, the first question is, can I do something to improve the performance of this function for_write_seq_xmit?
The second question involves what data is being written from the Fortran arrays, so please refer to the following example Fortran / C++ code. Suppose I try to write a double-precision array XRCST1(16383); I get the files dum-C.txt and dum-F.txt, and both are identical, and both are 131,072 bytes in size. (Figure 16384*8 bytes, I assume the extra data is the size of the array. OK, no problem). However, once I increase the size of XRCST1 to 16384 (interesting number, 2**14=16384), I get some problems: dum-F.txt is now 131,080 bytes (=16385*8, ok, follows the established pattern), but dum-C.txt is now 131,084 bytes. So, question #2 is, where are the 4 garbage bytes coming from? (As you can imagine, another part of my code needs to read back in this file from the disk, so the extra 4 bytes make for some very interesting kind of errors).
program main
use kernel32
C use ifposix
C
interface
function CallOpener(iOpt)
!DIR$ATTRIBUTES STDCALL,DECORATE::CallOpener
!DIR$ATTRIBUTES ALIAS:"CallOpener"::CallOpener
!DIR$ATTRIBUTES VALUE::iOpt
integer(8) iOpt,CallOpener
end function
end interface
C
DOUBLE PRECISION XRCST1
COMMON/XRCSTH/ XRCST1(16384)
C COMMON/XRCSTH/ XRCST1(16383)
C
C integer iArg,iRet
C integer(4) fd,ierror,inew,iold
C
EXTERNAL UOPEN
INTEGER(INT_PTR_KIND()) UOPEN
XRCST1=1.D0
C CALL PXFPOSIXIO (1,iold,ierror)
OPEN(UNIT=10,FILE='C:\data\dum-C.txt',
& FORM='UNFORMATTED',USEROPEN=UOpen)
OPEN(UNIT=11,FILE='C:\data\dum-F.txt',
& FORM='UNFORMATTED')
C write(10,*)"hi"
C flush(10)
C CALL PXFFILENO (10,fd,ierror)v
WRITE(10)XRCST1
WRITE(11)XRCST1
close(10)
close(11)
9 continue
iArg=0
iRet=CallOpener(iArg)
end
#include<Windows.h>
HANDLE hReadPipe, hWritePipe;
extern "C" __declspec(dllexport) __int64 __stdcall CallOpener(__int64 iOpt)
{
HANDLE hResult = CreateFileA("C:\\data\\dum-C.txt", GENERIC_WRITE, FILE_SHARE_READ, 0, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0);
char*Bytes=new char[1000000];//1e6
DWORD bytesRead, bytesWritten;
ReadFile(hReadPipe, Bytes, 1000000, &bytesRead, 0);
WriteFile(hResult, Bytes, bytesRead, &bytesWritten, 0);
CloseHandle(hReadPipe);
CloseHandle(hResult);
delete[]Bytes;
__int64 result;
result = 0;
return result;
}
extern "C" __declspec(dllexport) void* UOPEN(
_In_ char* lpFileName,
_In_ DWORD dwDesiredAccess,
_In_ DWORD dwShareMode,
_In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes,
_In_ DWORD dwCreationDisposition,
_In_ DWORD dwFlagsAndAttributes,
_In_opt_ HANDLE hTemplateFile,
_In_ int& UNIT)//,
// _In_ int& FLEN)
{
BOOL bResult1 = CreatePipe(&hReadPipe, &hWritePipe, 0, 1000000);//1e6
DWORD err1 = GetLastError();
return hWritePipe;
}
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
UNFORMATTED adds record length data with SEQUENTIAL access, and very large records may get split up. If you want to just write raw data, then I suggest using ACCESS='STREAM'. Or perhaps RECORDTYPE='FIXED' if all the records are the same size. An alternative is to memory-map the file using CreateFileMapping and MapViewOfFile to allow the data to go directly to disk without involving Fortran I/O. This can be a bit tricky to get right, but if you are saving massive amounts of data it may be useful.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Thanks Steve. The data is varying in size, but I will try some of the other options you suggested for performance.
I still don't understand though, why do I get a different-sized file if I let Fortran runtime create the File handle, versus providing my own handle to Fortran? The "Fortran Runtime Created File Handle" method consistently creates files that I can read back in, while the USEROPEN method does not.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
That's a separate problem I'm investigating. We did a lot of work on USEROPEN within the past year, but my own example doesn't work and I have to figure out why.

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page