delorie.com/archives/browse.cgi   search  
Mail Archives: djgpp-workers/1998/01/05/18:13:06

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 <randym AT acm DOT org>
Subject: malloc() with __dpmi_discard_page_contents()
Cc: dj AT delorie DOT com
Mime-Version: 1.0

--=====================_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 <malloc.h>
#include <dpmi.h>

#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<<I));
    }
}

--=====================_884063357==_
Content-Type: text/plain; charset="us-ascii"



--=====================_884063357==_--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019