Skip to content

Commit

Permalink
[8_1] Support mimalloc on macos/linux/windows, support jemalloc on linux
Browse files Browse the repository at this point in the history
  • Loading branch information
jingkaimori authored Jan 14, 2024
1 parent d0b3956 commit 653bd9b
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 40 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/ci-xmake-linux.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ on:
jobs:
linuxbuild:
runs-on: ubuntu-22.04
strategy:
matrix:
malloc:
[mimalloc, jemalloc, default]
steps:
- name: Install dependencies
run: |
Expand All @@ -50,7 +54,7 @@ jobs:
key: ${{ runner.os }}-xmake-${{ hashFiles('**/xmake.lua') }}
# Force xmake to a specific folder (for cache)
- name: config
run: xmake config --yes -vD
run: xmake config --yes -vD --malloc=${{ matrix.malloc }}
- name: build
run: xmake build --yes -vD
- name: test
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/ci-xmake-macos.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ on:
jobs:
macosbuild:
runs-on: macos-11
strategy:
matrix:
malloc:
[mimalloc, default]
steps:
- uses: actions/checkout@v2
with:
Expand Down Expand Up @@ -55,7 +59,7 @@ jobs:
key: ${{ runner.os }}-xmake-qt${{ matrix.qt_ver }}-${{ hashFiles('**/xmake.lua') }}

- name: config
run: xmake config --policies=build.ccache -o ${{ runner.workspace }}/build --yes -vD
run: xmake config --policies=build.ccache -o ${{ runner.workspace }}/build --yes -vD --malloc=${{ matrix.malloc }}
- name: build
run: xmake build --yes -vD
- name: test
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/ci-xmake-windows.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ on:
jobs:
windowsbuild:
runs-on: windows-2019
strategy:
matrix:
malloc:
[mimalloc, default]
env:
# Force xmake to a specific folder (for cache)
XMAKE_GLOBALDIR: ${{ github.workspace }}/.xmake-global
Expand All @@ -46,7 +50,7 @@ jobs:
${{ github.workspace }}/build/.build_cache
key: ${{ runner.os }}-xmake-${{ hashFiles('**/xmake.lua') }}
- name: config
run: xmake config --yes -vD
run: xmake config --yes -vD --malloc=${{ matrix.malloc }}
- name: build
run: xmake build --yes -vD
- name: test
Expand Down
29 changes: 1 addition & 28 deletions System/Memory/fast_alloc.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,46 +12,19 @@
#ifndef FAST_ALLOC_H
#define FAST_ALLOC_H

#include <stdlib.h>
#ifdef MIMALLOC
#include "mimalloc-override.h"
#endif
#ifdef JEMALLOC
#include "jemalloc/jemalloc.h"
#endif
#include "tm_ostream.hpp"
#include <stdlib.h>
#define WORD_LENGTH 8
#define WORD_LENGTH_INC 7
#define WORD_MASK 0xfffffffffffffff8
// WORD_LENGTH more than power of 2
#define MAX_FAST 264
#define BLOCK_SIZE 65536 // should be >>> MAX_FAST

/******************************************************************************
* Globals
******************************************************************************/

extern void*
alloc_table[MAX_FAST]; // Static declaration initializes with NULL's
extern char* alloc_mem;
#ifdef DEBUG_ON
extern char* alloc_mem_top;
extern char* alloc_mem_bottom;
#endif
bool break_stub (void* ptr);
extern size_t alloc_remains;
extern int allocated;
extern int large_uses;

#define alloc_ptr(i) alloc_table[i]
#define ind(ptr) (*((void**) ptr))

/******************************************************************************
* General purpose fast allocation routines
******************************************************************************/

extern void* safe_malloc (size_t s);
extern void* enlarge_malloc (size_t s);
extern void* fast_alloc (size_t s);
extern void fast_free (void* ptr, size_t s);
extern void* fast_new (size_t s);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@

#include "fast_alloc.hpp"

/******************************************************************************
* Globals
******************************************************************************/

void* alloc_table[MAX_FAST]; // Static declaration initializes with NULL's
char* alloc_mem= NULL;
#ifdef DEBUG_ON
Expand All @@ -27,12 +31,17 @@ int allocated = 0;
int fast_chunks = 0;
int large_uses = 0;
int MEM_DEBUG = 0;
int mem_used ();

/*****************************************************************************/
// General purpose fast allocation routines
/*****************************************************************************/

#define alloc_ptr(i) alloc_table[i]
#define ind(ptr) (*((void**) ptr))

bool break_stub (void* ptr);
int mem_used ();

void*
safe_malloc (size_t sz) {
void* ptr= malloc (sz);
Expand Down
66 changes: 66 additions & 0 deletions System/Memory/impl/je_malloc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@

/******************************************************************************
* MODULE : Fast memory allocation using jemalloc
* DESCRIPTION:
* COPYRIGHT : (C) 2023-2024 jingkaimori
*******************************************************************************
* This software falls under the GNU general public license version 3 or later.
* It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
* in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
******************************************************************************/

#include "assert.h"
#include "fast_alloc.hpp"
#include <jemalloc/jemalloc.h>

int mem_used ();

/*****************************************************************************/
// General purpose fast allocation routines
/*****************************************************************************/

void*
safe_malloc (size_t sz) {
void* ptr= malloc (sz);

if (ptr == NULL) {
cerr << "Fatal error: out of memory\n";
abort ();
}
return ptr;
}

void*
fast_alloc (size_t sz) {
return safe_malloc (sz);
}

void
fast_free (void* ptr, size_t sz) {
free (ptr);
}

void*
fast_new (size_t s) {
return safe_malloc (s);
}

void
fast_delete (void* ptr) {
free (ptr);
}

/******************************************************************************
* Statistics
******************************************************************************/

int
mem_used () {
cerr << "memory statistics is NOT IMPLEMENTED\n";
return 0;
}

void
mem_info () {
cout << "\n------- (NOT IMPLEMENTED) memory statistics -------\n";
}
75 changes: 75 additions & 0 deletions System/Memory/impl/mi_malloc.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@

/******************************************************************************
* MODULE : Fast memory allocation using mimalloc
* DESCRIPTION:
* COPYRIGHT : (C) 2023-2024 jingkaimori
*******************************************************************************
* This software falls under the GNU general public license version 3 or later.
* It comes WITHOUT ANY WARRANTY WHATSOEVER. For details, see the file LICENSE
* in the root directory or <http://www.gnu.org/licenses/gpl-3.0.html>.
******************************************************************************/

#include "assert.h"
#include "basic.hpp"
#include "fast_alloc.hpp"
#include <mimalloc.h>

/*****************************************************************************/
// General purpose fast allocation routines
/*****************************************************************************/

void*
safe_malloc (size_t sz) {
void* ptr= mi_malloc (mi_good_size (sz));
if (ptr == NULL) {
cerr << "Fatal error: out of memory\n";
abort ();
}
return ptr;
}

void*
fast_alloc (size_t sz) {
return safe_malloc (sz);
}

void
fast_free (void* ptr, size_t sz) {
mi_free (ptr);
}

void*
fast_new (size_t s) {
return safe_malloc (s);
}

void
fast_delete (void* ptr) {
mi_free (ptr);
}

/******************************************************************************
* Statistics
******************************************************************************/

bool
visit_mem (const mi_heap_t* heap, const mi_heap_area_t* heapinfo, void* block,
size_t blocksize, void* arg) {
int* count= (int*) arg;
*count+= heapinfo->used;
return true;
}

int
mem_used () {
mi_heap_t* heap = mi_heap_get_default ();
int count= 0;
mi_heap_visit_blocks (heap, false, visit_mem, &count);
return count;
}

void
mem_info () {
cout << "\n---------------- memory statistics ----------------\n";
cout << "malloc overrided:" << mi_is_redirected () << "\n";
}
29 changes: 28 additions & 1 deletion tests/System/Memory/fast_alloc_test.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
#include "a_lolly_test.hpp"
#include "fast_alloc.hpp"
#include "tm_timer.hpp"

int
usec_diff (time_t start, time_t end) {
if (start <= end) {
return end - start;
}
else {
return end + 1000000 - start;
}
}

struct Complex {
public:
Expand All @@ -23,7 +34,7 @@ TEST_CASE ("test for memory leaks") {

char* q_char= tm_new<char> ('z'); // here p_char is modified to 'z'

*p_char= 'c'; // here q_char is modified to 'c'
// *p_char= 'c'; // behavior of this code is unspecified, DO NOT DO THIS!
}

TEST_MEMORY_LEAK_INIT
Expand All @@ -40,6 +51,7 @@ TEST_CASE ("test basic data types") {
int* in[NUM];
long* lo[NUM];
double* dou[NUM];
int time= get_usec_time ();

for (int i= 0; i < NUM; i++) { // for gprof
ch[i]= tm_new<char> ();
Expand Down Expand Up @@ -68,6 +80,7 @@ TEST_CASE ("test basic data types") {
tm_delete (lo[i]);
tm_delete (dou[i]);
}
cout << "basic type: " << usec_diff (time, get_usec_time ()) << LF;
}

TEST_CASE ("test class") {
Expand All @@ -83,10 +96,12 @@ TEST_CASE ("test tm_*_array") {
#else
const size_t size_prim= 20000000, size_complex= 5000000;
#endif
int time = get_usec_time ();
p_complex= tm_new_array<uint8_t> (size_prim);
tm_delete_array (p_complex);
Complex* p_wide= tm_new_array<Complex> (size_complex);
tm_delete_array (p_wide);
cout << "large array: " << usec_diff (time, get_usec_time ()) << LF;
}

#ifndef OS_WASM
Expand All @@ -106,12 +121,24 @@ TEST_MEMORY_LEAK_RESET

TEST_CASE ("test large bunch of tm_*_array with class") {
Complex* volume[NUM];
int time= get_usec_time ();
for (int i= 0; i < NUM; i++) {
volume[i]= tm_new_array<Complex> (9);
}
for (int i= 0; i < NUM; i++) {
tm_delete_array (volume[i]);
}
cout << "frequent allocation of array: " << usec_diff (time, get_usec_time ())
<< LF;
time= get_usec_time ();
for (int i= 0; i < NUM; i++) {
volume[i]= tm_new_array<Complex> (9);
}
for (int i= 0; i < NUM; i++) {
tm_delete_array (volume[i]);
}
cout << "frequent allocation by reuse: " << usec_diff (time, get_usec_time ())
<< LF;
}

TEST_MEMORY_LEAK_ALL
Loading

0 comments on commit 653bd9b

Please sign in to comment.