Created
May 18, 2018 17:46
-
-
Save SeijiEmery/c930f84d3ef01d1e33b14822183b45dd to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| // utility/util/mem_bench.hpp | |
| // Copyright (C) 2017 Seiji Emery | |
| // | |
| // Memory + time benchmarking code: this hijacks (overloads) global new / delete | |
| // to trace memory allocations (very simple: # of allocations / frees + # bytes | |
| // allocated / freed), and adds a global variable that displays this stuff | |
| // from its dtor (guaranteed to be called after main() but before program exits). | |
| // | |
| // It also adds basic time profiling (global ctor / dtor) using std::chrono. | |
| // | |
| // All of this can be achieved externally ofc using time + valgrind (*nix), | |
| // and is perhaps preferable - but implementing these interally was an interesting | |
| // exercise nevertheless. | |
| // | |
| // This can all be disabled by compiling with -D NO_MEM_DEBUG. | |
| // | |
| #pragma once | |
| #ifndef NO_MEM_DEBUG | |
| #include <chrono> | |
| #include <iostream> | |
| struct MemTracer { | |
| void traceAlloc (size_t bytes) { ++numAllocations; allocatedMem += bytes; } | |
| void traceFreed (size_t bytes) { ++numFrees; freedMem += bytes;} | |
| private: | |
| size_t numAllocations = 0; // number of allocations in this program | |
| size_t numFrees = 0; // number of deallocations in this program | |
| size_t allocatedMem = 0; // bytes allocated | |
| size_t freedMem = 0; // bytes freed | |
| std::chrono::high_resolution_clock::time_point t0; // time at program start | |
| public: | |
| MemTracer () : t0(std::chrono::high_resolution_clock::now()) {} | |
| ~MemTracer () { | |
| using namespace std::chrono; | |
| auto t1 = high_resolution_clock::now(); | |
| std::cout << "\nUsed memory: " << ((double)allocatedMem) * 1e-6 << " MB (" << numAllocations << " allocations)\n"; | |
| std::cout << "Freed memory: " << ((double)freedMem) * 1e-6 << " MB (" << numFrees << " deallocations)\n"; | |
| std::cout << "Ran in " << duration_cast<duration<double>>(t1 - t0).count() * 1e3 << " ms\n"; | |
| } | |
| size_t memAllocated () const { return allocatedMem; } | |
| size_t memDeallocated () const { return freedMem; } | |
| size_t allocCount () const { return numAllocations; } | |
| size_t deallocCount () const { return numFrees; } | |
| } g_memTracer; | |
| void* operator new (size_t size) throw(std::bad_alloc) { | |
| g_memTracer.traceAlloc(size); | |
| size_t* mem = (size_t*)std::malloc(size + sizeof(size_t)); | |
| if (!mem) { | |
| throw std::bad_alloc(); | |
| } | |
| mem[0] = size; | |
| return (void*)(&mem[1]); | |
| } | |
| void operator delete (void* mem) throw() { | |
| auto ptr = &((size_t*)mem)[-1]; | |
| g_memTracer.traceFreed(ptr[0]); | |
| std::free(ptr); | |
| } | |
| #endif // NO_MEM_DEBUG |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment