Thank you Pavel, it’s definitely easier, but it seems that ZwReadFile
with caching is really much worse (performance) than file mapping - and
I have no idea why.
But maybe (I’d hope) there’s something wrong with my tests.
Test file (1 GB) is opened this way:
status = ZwCreateFile
(
& FileHandle,
GENERIC_READ | GENERIC_WRITE | SYNCHRONIZE,
&ObjectAttributes,
&IoStatusBlock,
NULL,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_READ,
FILE_OPEN_IF,
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT,
NULL,
0
);
The following code takes around 20s to complete, when it’s called
repetitively, it’s takes always the same amout of time.
LARGE_INTEGER beforeTime;
KeQuerySystemTime(&beforeTime);
ULONG seed = 26548894;
char buffer[1024];
for (int i = 0; i < 100 * 1000; i++)
{
ULONG rand = RtlRandomEx(&seed) % (1024 * 256);
LARGE_INTEGER offset;
offset.QuadPart = rand * 1024;
ZwReadFile(FileHandle, NULL, NULL, NULL, &IoStatusBlock,
buffer, 1024, &offset, NULL);
}
LARGE_INTEGER afterTime;
KeQuerySystemTime(&afterTime);
int length = ((afterTime.QuadPart - beforeTime.QuadPart) / 10 /
1000 / 1000);
DbgPrint(“Length = %d\n”, length);
On the other hand, this code takes around 2s, file is mapped to
BaseAddress:
LARGE_INTEGER beforeTime2;
KeQuerySystemTime(&beforeTime2);
ULONG seed = 26548894;
char buffer2[1024];
for (int j = 0; j < 100 * 1000; j++)
{
ULONG rand = RtlRandomEx(&seed) % (1024 * 256);
memcpy(buffer2, (char *) BaseAddress + (rand * 1024),
1024);
}
LARGE_INTEGER afterTime2;
KeQuerySystemTime(&afterTime2);
int length2 = ((afterTime2.QuadPart - beforeTime2.QuadPart) / 10
/ 1000 / 1000);
DbgPrint(“Length2 = %d\n”, length2);
Important fact - I ran these two tests separately.
-----Original Message-----
From: xxxxx@lists.osr.com
[mailto:xxxxx@lists.osr.com] On Behalf Of Pavel
Lebedynskiy
Sent: Tuesday, May 08, 2012 23:12
To: Windows System Software Devs Interest List
Subject: RE: [ntdev] ZwCreateSection and extending the section
My target is to map arbitrarily large file - what’s more than
problematic on 32bit platform using ZwMapViewOfSection(), I need to
support random R/W access to whole file.
The cache manager also can’t map arbitrarily large files. It only has
(at most) 2 GB of available VA space on 32 bits, so for any file that is
larger than that the cache manager will have to map/unmap portions of
the file to perform IO.
If you really wanted to you could do the same thing manually with
ZwMapViewOfSection. But, as others have said, it’s much easier to just
use normal read/write APIs and let the cache manager do the caching.
NTDEV is sponsored by OSR
For our schedule of WDF, WDM, debugging and other seminars visit:
http://www.osr.com/seminars
To unsubscribe, visit the List Server section of OSR Online at
http://www.osronline.com/page.cfm?name=ListServer