flat assembler
Message board for the users of flat assembler.
![]() |
Author |
|
Torrey 20 Jun 2006, 10:54
Why not use VirtualAlloc and VirtualFree since you have the file size? It'd be similar to the method you're using, but would free up the RAM it used. This method wouldn't be recommended for very large files.
|
|||
![]() |
|
quasar 20 Jun 2006, 11:12
You can't. To do this as it should you have to allocate your buffer through GlobalAlloc/VirtualAlloc and GlobalFree it when you don't need it anymore.
|
|||
![]() |
|
jbojarczuk 09 Sep 2006, 01:58
Use VirtualAlloc to alloc the memory; this will make sure the memory is sector-aligned.
When you call CreateFile, use the FILE_FLAG_NO_BUFFERING flag. When you write the file, pass in this buffer. Because of the flag, windows will not use an intermediate buffer on this file, and so will not hold resources. The caveat for this is that buffers for reading/writing to disk must be sector aligned, otherwise... (It must be REALLY BAD for the manual to not say what happens!!! ![]() |
|||
![]() |
|
LocoDelAssembly 09 Sep 2006, 03:08
Try with http://msdn.microsoft.com/library/default.asp?url=/library/en-us/fileio/fs/flushfilebuffers.asp
Since those buffers are stored to disk after calling that function the memory manager can use that memory when it wants without wainting for any I/O. |
|||
![]() |
|
f0dder 09 Sep 2006, 11:00
Process file in chunks instead of one read and one write.
|
|||
![]() |
|
LocoDelAssembly 09 Sep 2006, 14:44
f0dder, he process the file in 6000000 bytes chucks, the problen here is that he says that after processing 100 MB he looses 100 MB of RAM memory.
mmmm, looking deeper in the code I see that if the file is more that 6000000 bytes the buffer will overflow. You have to read in chucks as f0dder says and if that wastes you RAM then use FlushFileBuffers in the loop. Sorry if I'd assume wrong that those 100 MB was after executing WriteFile many times, not only once. |
|||
![]() |
|
f0dder 09 Sep 2006, 14:50
Also, "losing" memory is a pretty loose description.
The application shouldn't keep having a high memory footprint if the buffers are allocated; the total memory stats shown by taskmgr will keep being high, but that's because memory is used for filesystem cache. That is *not* a problem, the memory will be freed if it becomes necessary. Recall the old saying "unused memory is wasted memory". Filesystem cache is a good thing. |
|||
![]() |
|
LocoDelAssembly 09 Sep 2006, 15:16
Yes, but I think that Windows prefer to cache some file contents by using non dirty memory pages (when there is no more physical memory available) instead of just write to disk. That's the reason why I think that he should use FlushFileBuffers. The same goes to file mapping, if you are writing too many pages you should use FlushViewOfFile to prevent monopolization of the physical memory by that file mapping. I did a expirement writing sequentially over file mapping getting a tremendous system performance loss without FlushViewOfFile. Without FlushViewOfFile the program finishes its works very fast (only the first time), but all the other processes starts a lot of swapping because of this.
My conclusion is that is convinient to force file buffers writing to disk to make the memory occupied by those buffers ready to use for something else (but the buffers stills in memory to be used as cache, flushing just makes them more discardable). |
|||
![]() |
|
f0dder 09 Sep 2006, 15:20
Sounds like a good piece of advice - you just need to flush at strategically good times. Ie, better to do it after you're done writing, not after each 4kb write you do
![]() |
|||
![]() |
|
okasvi 09 Sep 2006, 15:28
I think doing it strategically is not just about size, more like doing it between every 16mb's or every few minutes... I think ie. most torrent-apps(good example as it does alot of writing to file) uses something like that... but definately flushing the file every now and then is good practice
|
|||
![]() |
|
f0dder 09 Sep 2006, 15:31
Windows does cache flushing "every now and then" already... It's got a background thread running for just that purpose. Look at "inside windows 2000".
|
|||
![]() |
|
LocoDelAssembly 09 Sep 2006, 15:35
Quote:
Actually I'd call FlushViewOfFile at every 128 MB of written data ![]() Code: format PE GUI 4.0 include 'win32axp.inc' INVALID_HANDLE_VALUE equ -1 FILE_SIZE = 1024*1024*1024 start: ; Apertura del archivo invoke CreateFile, 'test.dat',\ ; lpFileName GENERIC_READ or GENERIC_WRITE,\ ; dwDesiredAccess 0,\ ; dwShareMode NULL,\ ; lpSecurityAttributes OPEN_ALWAYS,\ ; dwCreationDistribution FILE_ATTRIBUTE_NORMAL,\ ; dwFlagsAndAttributes NULL ; hTemplateFile cmp eax, INVALID_HANDLE_VALUE mov esi, eax invoke SetFilePointer, esi, FILE_SIZE, 0, FILE_BEGIN invoke SetEndOfFile, esi @@: ; Creación del mapeo del archivo invoke CreateFileMapping, esi,\ ; hFile NULL,\ ; lpFileMappingAttributes PAGE_READWRITE,\ ; flProtect 0,\ ; dwMaximumSizeHigh 0,\ ; dwMaximumSizeLow NULL ; lpName mov esi, eax ; Mapeo del archivo a memoria xor ebx, ebx invoke MapViewOfFile, esi,\ ; hFileMappingObject FILE_MAP_WRITE,\ ; dwDesiredAccess 0,\ ; dwFileOffsetHigh ebx,\ ; dwFileOffsetLow FILE_SIZE ; dwNumberOfBytesToMap mov edi, eax mov esi, eax .loop: mov ecx, FILE_SIZE/8 rep stosb invoke FlushViewOfFile, esi, 0 add ebx, FILE_SIZE/8 cmp ebx, FILE_SIZE jb .loop exit: invoke ExitProcess, 0 .end start f0dder is right, Windows already do that, the problem is when you write very fast ![]() [edit] I don't know why I used Code: add ebx, FILE_SIZE/8 cmp ebx, FILE_SIZE jb .loop ![]() Code: mov ebx, FILE_SIZE/(FILE_SIZE/8) .loop: mov ecx, FILE_SIZE/8 rep stosb invoke FlushViewOfFile, esi, 0 dec ebx jnz .loop |
|||
![]() |
|
< Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.