From llbird's C/C ++ world
This is an experimental program. Although the algorithm implementation is weak, when the compiler is optimized,
The performance is much better than the memory management with global new Delete. I have considered multithreading here.
It seems that the memory pool can significantly improve the performance of a program that uses a large amount of memory allocation;
If you have time, I will improve the algorithm. if you can see it, please give me some advice. I am not professional and very weak in algorithm;
There are also some problems with the memory allocation of arrays;
General memory allocation mode of the following Array
Void * operator new [] (size_t size );
Void operator Delete [] (void * P, size_t size );
Unfortunately, the size in new is not the same as the size in delete in VC and BC (G ++ is the same, better );
In this case, the pointer and corresponding size need to be saved for the array allocation (hash is generally used), which takes a lot of time;
# Pragma warning (Disable: 4530)
# Pragma warning (Disable: 4786)
# Include <map>
# Include <cassert>
# Include <iostream>
# Include <algorithm>
# Include <exception>
# Include <iomanip>
# Include <list>
Using namespace STD;
# Include <windows. h>
Template <size_t preallocsize = 1024>
Class memorypool
{
Protected:
Struct memoryblock
{
Char * _ address;
Size_t _ size;
Memoryblock * _ next;
Memoryblock (void * pbegin, size_t size): _ address (char *) pbegin), _ SIZE (size), _ next (null ){};
};
Struct lock
{
Critical_section & Cs;
Lock (critical_section & CS): CS (CS) {entercriticalsection (& CS );}
~ Lock () {leavecriticalsection (& CS );}
};
Char _ buffer [preallocsize];
Char * _ begin, * _ end;
Critical_section _ cslock;
List <memoryblock *> _ memorylist;
Void createlist ()
{
_ Memorylist. push_back (New memoryblock (_ begin, preallocsize ));
}
Void freelist ()
{
List <memorypool: memoryblock *>: iterator ITER;
For (iter = _ memorylist. Begin (); iter! = _ Memorylist. End (); ITER ++)
Delete (* ITER );
_ Memorylist. Clear ();
}
Void * ffa_alloc (size_t size) // first fit Algorithm
{
Char * P = NULL;
List <memorypool: memoryblock *>: iterator ITER;
For (iter = _ memorylist. Begin (); iter! = _ Memorylist. End (); ITER ++)
{
If (size <(* ITER)-> _ SIZE)
{
P = (* ITER)-> _ address, (* ITER)-> _ address + = size, (* ITER)-> _ size-= size;
Break;
}
Else
{
If (size = (* ITER)-> _ SIZE)
{
P = (* ITER)-> _ address;
Delete (* ITER );
_ Memorylist. Erase (ITER );
Break;
}
}
}
Return P;
}
Bool ffa_free (char * P, size_t size)
{
If (P <_ begin | P + size> _ end)
Return false;
List <memorypool: memoryblock *>: iterator ITER, temp_iter;
For (iter = _ memorylist. Begin (); iter! = _ Memorylist. End (); ITER ++)
{
If (P <(* ITER)-> _ address) // find the insert point
{
If (p + size> (* ITER)-> _ address) // Error
Return false;
If (iter = _ memorylist. Begin ())
{
If (p + size = (* ITER)-> _ address) // Union next_node
(* ITER)-> _ address = P, (* ITER)-> _ SIZE + = size;
Else // insert
_ Memorylist. insert (ITER, new memoryblock (p, size ));
}
Else
{
Temp_iter = ITER, temp_iter --; // get pre_node
If (* temp_iter)-> _ SIZE + (* temp_iter)-> _ address = P) // must Union pre_node
{
If (p + size = (* ITER)-> _ address) // Union next_node and pre_node
{
(* Temp_iter)-> _ SIZE + = size + (* ITER)-> _ size;
_ Memorylist. Erase (ITER );
}
Else // just Union pre_node
(* Temp_iter)-> _ SIZE + = size;
}
Else
{
If (p + size = (* ITER)-> _ address) // Union next_node
(* ITER)-> _ SIZE + = size, (* ITER)-> _ address = P;
Else
_ Memorylist. insert (ITER, new memoryblock (p, size ));
}
}
Return true;
} // If (P <(* ITER)-> _ begin)
} //
If (_ memorylist. Size () = 0) // null list
_ Memorylist. insert (_ memorylist. End (), new memoryblock (p, size ));
Else // push back of list
{
List <memorypool: memoryblock *>: reverse_iterator r_iter = _ memorylist. rbegin ();
If (* r_iter)-> _ SIZE + (* r_iter)-> _ address = P) // must Union pre_node
(* R_iter)-> _ SIZE + = size;
Else
_ Memorylist. insert (_ memorylist. End (), new memoryblock (p, size ));
}
Return true;
}
Void * bfa_alloc (size_t size) // best fit Algorithm
{
}
Bool bfa_free (char * P, size_t size)
{
}
Void * wfa_alloc (size_t size) // worst fit Algorithm
{
}
Bool wfa_free (char * P, size_t size)
{
}
Public:
Memorypool () //: _ memoryhash (preallocsize/16)
{
_ Begin = _ buffer, _ end = _ buffer + preallocsize;
Initializecriticalsection (& _ cslock );
Createlist ();
}
~ Memorypool ()
{
Deletecriticalsection (& _ cslock );
Freelist ();
}
Void * alloc (size_t size)
{
Lock (_ cslock );
Void * P = ffa_alloc (size );
Return P? P: malloc (size );
}
Void free (void * address, int size)
{
Lock (_ cslock );
If (! Size)
Size = 1;
If (! Ffa_free (char *) Address, size ))
{
Printf ("/nfree error: Address % P size % d/N", address, size );
Free (Address );
}
}
Void printlist ()
{
Printf ("/N ");
Int I;
If (_ memorylist. Size () = 0)
{
Printf ("no memory! /N ");
Return;
}
List <memorypool: memoryblock *>: iterator ITER;
For (I = 0, iter = _ memorylist. Begin (); iter! = _ Memorylist. End (); ITER ++, I ++)
Printf ("% d: Address % p offset % d, size % d;/N ",
I, (* ITER)-> _ address, (* ITER)-> _ address-_ begin, (* ITER)-> _ size );
}
};
Class Object
{
Public:
Static memorypool <2*1024*1024> _ mp;
Void * operator new (size_t size)
{
Return _ mp. alloc (size );
};
Void operator Delete (void * P, size_t size)
{
_ Mp. Free (p, size );
};
};
Memorypool <2*1024*1024> Object: _ mp;
Int main (INT argc, char * argv [])
{
Int I;
Object *** x = new object * [1000000];
Int bt = gettickcount ();
For (I = 0; I <1000000; I ++)
X [I] = new object ();
For (I = 0; I <1000000; I ++)
Delete X [I];
Cout <"use memory pool" <gettickcount ()-BT <Endl;
Bt = gettickcount ();
For (I = 0; I <1000000; I ++)
X [I] =: new object [10];
For (I = 0; I <1000000; I ++)
: Delete X [I];
Cout <"Use global new" <gettickcount ()-BT <Endl;
Return 0;
}