Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[8_1] Support mimalloc on macos/linux/windows, support jemalloc on linux #210

Merged
merged 17 commits into from
Jan 14, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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;
jingkaimori marked this conversation as resolved.
Show resolved Hide resolved
}

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
Loading