cmu-db / peloton

The Self-Driving Database Management System
http://pelotondb.io
Apache License 2.0
2.03k stars 622 forks source link

overload new/delete operator with jemalloc #171

Closed ranxian closed 8 years ago

ranxian commented 8 years ago

Currently we are not actually using jemalloc, because the new operator is not overloaded to use jemalloc. I would like to fix this, is there a global header/source that is included by all as long as we overload them somewhere that is linked in libpeloton, jemalloc would work

ranxian commented 8 years ago

I also didn't see where do we include <jemalloc/jemalloc.h>, jemalloc is also not in the link flags, are we really using jemalloc?

jarulraj commented 8 years ago

No, we are currently not using jemalloc. Instead of overloading those operators, can you alter the linker flags to use -ljemalloc by adding the autoconf check (jemalloc.m4) ? Also, add it to the installed package list.

https://stackoverflow.com/questions/9521226/c-stl-with-jemalloc https://github.com/chriso/bitset/blob/master/configure.ac#L27 https://github.com/chriso/bitset/blob/master/m4/jemalloc.m4 https://github.com/cmu-db/peloton/blob/master/scripts/installation/packages.sh

ranxian commented 8 years ago

@jarulraj -ljemalloc alone will not work, the suggested way to make all new/delete and std::allocator to use jemalloc is to overload these operators (it is suggested in the first link you posted)

yingjunwu commented 8 years ago

I think I've set the link flag, haven't I?

ranxian commented 8 years ago

@yingjunwu Yes I saw a -ljemalloc-dev, but that alone would not work, we are still using malloc

ranxian commented 8 years ago

simple benchmark:

#include <vector>
#include <boost/thread.hpp>
#include <jemalloc/jemalloc.h>
#include <iostream>

/* uncomment to replace with jemalloc
void* operator new(std::size_t sz) {
    return malloc(sz);
}
void operator delete(void* ptr) noexcept
{
    free(ptr);
}
*/

int main() {
    std::vector<boost::thread> threads;

    for (int i = 0; i < 12; i++) {
        threads.push_back(boost::thread([]() {
            for (int j = 0; j < 1024*1024; j++) {
                int *number = new int;
                *number -= 1;
                delete number;
                std::vector<int> vec(1024);
                vec[1023] = -1;
            }
        }));
    }

    for (auto &thread : threads) {
        thread.join();
    }

    return 0;
}

Without those overloaded operators

g++ -O3 -std=c++11 -o test test_jemalloc.cpp -lboost_system -lboost_thread -ljemalloc -lpthread
time ./test
./test  3.69s user 0.01s system 914% cpu 0.404 total

With overloaded operators

g++ -O3 -std=c++11 -o test test_jemalloc.cpp -lboost_system -lboost_thread -ljemalloc -lpthread
time ./test
./test  0.01s user 0.00s system 166% cpu 0.005 total

It's on the MemSQL machine

yingjunwu commented 8 years ago

I think you can just use LD_PRELOAD. It's not very cool to change the source code for using jemalloc.

yingjunwu commented 8 years ago

https://github.com/jemalloc/jemalloc/wiki/Getting-Started

jarulraj commented 8 years ago

I think that the issue is the order of the link flags. Add -ljemalloc before another other libraries, so that they don't load in glibc malloc, and see if that helps. http://www.canonware.com/pipermail/jemalloc-discuss/2013-July/000619.html

yingjunwu commented 8 years ago

you can also learn from silo: https://github.com/stephentu/silo. They support jemalloc, tcmalloc, hoard etc. They did not change the source code.

ranxian commented 8 years ago

They did

https://github.com/stephentu/silo/blob/master/memory.cc

yingjunwu commented 8 years ago

we can talk offline.

jarulraj commented 8 years ago

Finished this in 1c16a21810.