Message-Id: <3.0.1.32.19980105170917.007e8100@yacker.xiotech.com> Date: Mon, 05 Jan 1998 17:09:17 -0600 To: djgpp-workers AT delorie DOT com From: Randy Maas Subject: malloc() with __dpmi_discard_page_contents() Cc: dj AT delorie DOT com Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=====================_884063357==_" Precedence: bulk --=====================_884063357==_ Content-Type: text/plain; charset="us-ascii" I did a little experiment to see if calling __dpmi_discard_page_contents() before or during a free (to invalidate the now useless pages) would improve performance. The thinking being a free'd page in memory shouldn't be put to disk. I've attached the source I used for the test. In a nutshell, I allocated and free'd a memory buffer NCycles times. Each the buffer is allocated much bigger than before (spanning lots of pages), and memset()'d to touch all of the pages. The normal version used plain malloc free, and the test version used called __dpmi_discard_page_contents() before it free()'d them. Here is the timing results from the profiler: CPU NCycles Total Time TotalTime (Normal) (w/Discrd) 386 14 48.4 48.5 486 14 2.7 2.7 586 14 4.1 3.9 486 16 100.2 99.4 586 16 22.0 21.9 the 386 is a 386/16 with 2MB (the reason for 14 cycles being used). the 486 is a 486/25 with 48MB the 586 is a pentium/133 with 8MB all used cwsdpmi 3. all times rounded to 1/10 per second. This is more of a pathological app than a normal one, and it uses the djgpp v2.01 malloc (not the new one). It does look like the __dpmi_discard_page_contents() may be worth investigating to help speed up malloc()/free(), especially with the new one being used. I'd recommend a more thorough test, of course. Counter note: The profile also indicates that memset() acts faster as well, presumably because the page doesn't have to be swapped in to modify it. I did another program to see if discarding pages before a memset, or copy, etc. would be faster: its slower. I hope this helps the malloc() debate along. Randy --=====================_884063357==_ Content-Type: text/plain; charset="us-ascii" Content-Disposition: attachment; filename="Mtest.c" #include #include #define NCycles (14) #if defined(TEST) # define FREE(x) my_free(x) # define MALLOC(x) my_malloc(x) #else # define FREE(x) free(x) # define MALLOC(x) malloc(x) #endif char* my_malloc(size_t size) { char* ret = malloc(size+sizeof(size)); *(size_t*)ret = size; return ret + sizeof(size); } void my_free(char* ptr) { __dpmi_meminfo Info; Info.size = *(size_t*)(ptr-sizeof(size_t)); Info.address =(ptr-sizeof(size_t)); __dpmi_discard_page_contents(&Info); free(ptr-sizeof(size_t)); } void test(size_t Size) { char* Ptr = MALLOC(Size); if (!Ptr) {printf("failed at %ld bytes\n", Size); exit(-1);} /* Touch the page */ bzero(Ptr, Size); FREE(Ptr); } main() { unsigned I; for (I = 0; I < NCycles; I++) { /* Allocate, but not on a page boundary */ test(512+(1024<