Raised This Month: $12 Target: $400
 3% 

[INC] Dynamic memory (Heap)


Post New Thread Reply   
 
Thread Tools Display Modes
Author Message
Kailo
Senior Member
Join Date: Sep 2014
Location: Moscow, Russia
Old 08-28-2019 , 16:27   [INC] Dynamic memory (Heap)
Reply With Quote #1

As SourcePawn not have real heap, i created my one.

This include file provide functions to create and use statically allocated memory heap inside your plugin.
Heap is based on global one-dimensional array.
Doubly linked list projected on array. Free node can be splited to busy and free parts.
When busy node freed, it join with near free.
On left 0-sized busy node as border.
On right reversed array for BST nodes.
Free list nodes cached in BST.

Usage
PHP Code:
// You need to use this defines before including
#define HEAP_SIZE 16384 // optional define, to override heap size; sized in cells
#define BST_ALLOC_COUNT 256 // optional define, to override BST allocation step size; sized in node count (number of objects)
#define FREE_MEM_SLICE_MIN 8 // optional define, to override memory sliceing limitation

#define DEBUG_HEAP_MEMORY_FULL // define it, to turn on all validation checks
#define DEBUG_HEAP_MEMORY_INIT // define it, to turn on heap initialization check
#define DEBUG_HEAP_MEMORY_SIZE // define it, to turn on passed size validation
#define DEBUG_HEAP_MEMORY_BOUNDS // define it, to turn on passed address validation (careful, can increase read/write by 1.5 times)
#define DEBUG_HEAP_MEMORY_MAGIC // define it, to turn on magic value validation
#define DEBUG_HEAP_MEMORY_STATUS // define it, to turn on status validation

// Use 0 as null pointer (address)
// Address represent an integral value above 0 (array cell index, from where allocated memory started)

int memalloc(int size);
void free(int adr);
int realloc(int adrint size);

void store(int adrany value);
any load(int adr);
void mempaste(int adr, const any[] array, int size);
void memcopy(int adrany[] array, int size);
void memmove(int fromadrint toadrint size);
void memmover(int fromadrint toadrint size);
void mempastestr(int adr, const char[] strint size);
void memcopystr(int adrchar[] strint size); 
You can wrap address with methodmap to create almost full OOP in SP.

Profiling
Tested on CS:GO server under 2x2.66 GHz CPU
Average of 10
Code:
0.001208 s for first alloc and free with initialization

0.000254 s for allocate 1000 blocks by 64 cells
0.000955 s for read 64000 cells
0.001092 s for write 64000 cells
0.000265 s for free 1000 blocks by 64 cells
PHP Code:
#include <profiler>

#define HEAP_SIZE 131072
#include <memory>

#define OBJECT_NUMBER 1000
#define OBJECT_SIZE 64

Handle prof;
int count 10;

public 
void OnPluginStart()
{
    
prof CreateProfiler();
    
StartProfiling(prof);
    
free(memalloc(10));
    
StopProfiling(prof);
    
PrintToServer("%f s"GetProfilerTime(prof));

    
Frame(0);
}

public 
void Frame(any data)
{
    
count--;
    
MakeProf();
    if (
count != 0)
        
RequestFrame(Frame);
}

void MakeProf()
{
    
int blocks[OBJECT_NUMBER], i;
    
    
int nv;
    
StartProfiling(prof);
    for (
0OBJECT_NUMBERi++)
    {
        
blocks[i] = memalloc(OBJECT_SIZE);
    }
    
StopProfiling(prof);
    
PrintToServer("%f s for allocate %i blocks by %i cells"GetProfilerTime(prof), OBJECT_NUMBEROBJECT_SIZE);
    
    
StartProfiling(prof);
    for (
0OBJECT_NUMBERi++)
    {
        for (
0OBJECT_SIZEn++)
        {
            
load(blocks[i] + n);
        }
    }
    
StopProfiling(prof);
    
PrintToServer("%f s for read %i cells"GetProfilerTime(prof), OBJECT_NUMBER OBJECT_SIZE);
    
    
StartProfiling(prof);
    for (
0OBJECT_NUMBERi++)
    {
        for (
0OBJECT_SIZEn++)
        {
            
store(blocks[i] + nv);
        }
    }
    
StopProfiling(prof);
    
PrintToServer("%f s for write %i cells"GetProfilerTime(prof), OBJECT_NUMBER OBJECT_SIZE);
    
    
StartProfiling(prof);
    for (
0OBJECT_NUMBERi++)
    {
        
free(blocks[i]);
    }
    
StopProfiling(prof);
    
PrintToServer("%f s for free %i blocks by %i cells"GetProfilerTime(prof), OBJECT_NUMBEROBJECT_SIZE);

Download from GitHub
__________________

Last edited by Kailo; 09-01-2019 at 13:47.
Kailo is offline
RumbleFrog
Great Tester of Whatever
Join Date: Dec 2016
Location: Fish Tank
Old 08-28-2019 , 17:13   Re: [INC] Dynamic memory (Heap)
Reply With Quote #2

This is dope, can't wait to see applications using this.

Last edited by RumbleFrog; 08-28-2019 at 17:55.
RumbleFrog is offline
OSWO
Senior Member
Join Date: Jul 2015
Location: United Kingdom, London
Old 09-02-2019 , 04:17   Re: [INC] Dynamic memory (Heap)
Reply With Quote #3

Is it possible to add a size lookup?
__________________
SourceTimer | WeaponSkins++ | BasePlugins++ https://github.com/OSCAR-WOS
OSWO is offline
Kailo
Senior Member
Join Date: Sep 2014
Location: Moscow, Russia
Old 09-14-2020 , 20:04   Re: [INC] Dynamic memory (Heap)
Reply With Quote #4

New version 1.2.0 is released:
RB-Tree balance
__________________
Kailo is offline
Reply


Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -4. The time now is 21:51.


Powered by vBulletin®
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Theme made by Freecode