diff --git a/src/GC/docs/benchmarking.md b/src/GC/docs/benchmarking.md new file mode 100644 index 0000000..c2b9279 --- /dev/null +++ b/src/GC/docs/benchmarking.md @@ -0,0 +1,21 @@ +# Benchmarking + +free_overlap(): + 9_000 nodes: + With indexing: + Execution time: 22624 ≈ 22ms ≈ 0s. + Without indexing: + Execution time: 24891 ≈ 24ms ≈ 0s. + + 90_000 nodes: + With indexing: + Execution time: 693642 ≈ 693ms ≈ 0s. + Without indexing: + Execution time: 712297 ≈ 712ms ≈ 0s. + +Linked list test: + 50_000 nodes: + With marking all: + Execution time: 13911478 ≈ 13911ms ≈ 13s. + Without marking: + Execution time: 234361 ≈ 234ms ≈ 0s. \ No newline at end of file diff --git a/src/GC/include/heap.hpp b/src/GC/include/heap.hpp index ac8bdd8..c373d3c 100644 --- a/src/GC/include/heap.hpp +++ b/src/GC/include/heap.hpp @@ -9,8 +9,8 @@ #include "chunk.hpp" #include "profiler.hpp" -#define HEAP_SIZE 65536 -#define FREE_THRESH (uint)20 +#define HEAP_SIZE 2097152 //65536 +#define FREE_THRESH (uint) 100000 #define DEBUG namespace GC @@ -94,6 +94,7 @@ namespace GC void check_init(); // print dummy things void print_contents(); // print dummy things void print_allocated_chunks(Heap *heap); // print the contents in m_allocated_chunks + void print_summary(); #endif }; } \ No newline at end of file diff --git a/src/GC/lib/heap.cpp b/src/GC/lib/heap.cpp index f92088c..325443c 100644 --- a/src/GC/lib/heap.cpp +++ b/src/GC/lib/heap.cpp @@ -130,7 +130,7 @@ namespace GC // Check if there are any freed chunks large enough for current request for (size_t i = 0; i < heap.m_freed_chunks.size(); i++) { - // auto chunk = Heap::get_at(heap.m_freed_chunks, i); + //auto chunk = Heap::get_at(heap.m_freed_chunks, i); auto chunk = heap.m_freed_chunks[i]; auto iter = heap.m_freed_chunks.begin(); advance(iter, i); @@ -374,7 +374,7 @@ namespace GC { std::vector filtered; size_t i = 0; - // auto prev = Heap::get_at(heap.m_freed_chunks, i++); + //auto prev = Heap::get_at(heap.m_freed_chunks, i++); auto prev = heap.m_freed_chunks[i++]; prev->m_marked = true; filtered.push_back(prev); @@ -382,7 +382,7 @@ namespace GC for (; i < heap.m_freed_chunks.size(); i++) { prev = filtered.back(); - // auto next = Heap::get_at(heap.m_freed_chunks, i); + //auto next = Heap::get_at(heap.m_freed_chunks, i); auto next = heap.m_freed_chunks[i]; auto p_start = (uintptr_t)(prev->m_start); auto p_size = (uintptr_t)(prev->m_size); @@ -544,6 +544,27 @@ namespace GC } } + void Heap::print_summary() + { + Heap &heap = Heap::the(); + if (heap.m_allocated_chunks.size()) + { + cout << "\nALLOCATED CHUNKS #" << dec << heap.m_allocated_chunks.size() << endl; + } + else + { + cout << "NO ALLOCATIONS\n" << endl; + } + if (heap.m_freed_chunks.size()) + { + cout << "\nFREED CHUNKS #" << dec << heap.m_freed_chunks.size() << endl; + } + else + { + cout << "NO FREED CHUNKS" << endl; + } + } + void Heap::set_profiler(bool mode) { Heap &heap = Heap::the(); diff --git a/src/GC/tests/h_test.cpp b/src/GC/tests/h_test.cpp index 2755149..2428383 100644 --- a/src/GC/tests/h_test.cpp +++ b/src/GC/tests/h_test.cpp @@ -16,13 +16,8 @@ Node *create_chain(int depth) { Node *node = static_cast(GC::Heap::alloc(sizeof(Node))); node->id = depth-i; node->child = nodes[i]; - //node->child = nodes.at(i-1); - std::cout << "Child of node: " << node << " is: " << node->child << std::endl; nodes.push_back(node); } - for (size_t i = 0; i < nodes.size(); i++) { - std::cout << "Element at " << i << ":\t" << nodes.at(i) << std::endl; - } return nodes[depth]; } else @@ -40,10 +35,8 @@ void detach_pointer(long **ptr) { Node *test_chain(int depth, bool detach) { auto stack_start = reinterpret_cast(__builtin_frame_address(0)); - std::cout << "Stack start from test_chain:\t" << stack_start << std::endl; Node *node_chain = create_chain(depth); - // This generates a segmentation fault (should be investigated further) if (detach) node_chain->child = nullptr; return node_chain; @@ -66,38 +59,34 @@ void test_some_types() { } int main() { + using namespace std::literals; + + auto start = std::chrono::high_resolution_clock::now(); + //std::cout << "Value of start: " << start.time_since_epoch().count() << std::endl; GC::Heap::init(); GC::Heap &gc = GC::Heap::the(); gc.set_profiler(true); gc.check_init(); auto stack_start = reinterpret_cast(__builtin_frame_address(0)); - std::cout << "Stack start from main:\t" << stack_start << std::endl; - - // char *c = static_cast(gc->alloc(sizeof(char))); // 0x0 | 0x0 - // int *i = static_cast(gc->alloc(sizeof(int))); // 0x1-0x4 | 0x4-0x8 - // char *c2 = static_cast(gc->alloc(sizeof(char)));// 0x5 | 0x9-0x - // long *l = static_cast(gc->alloc(sizeof(long))); // 0x6-0xd | 0x - - // This is allocated outside of the scope of the GC (if gc->init() isn't called), thus garbage -/* long *longs; - std::cout << "Pointer to ints:\t" << longs << std::endl; - for (int i = 0; i < 21; i++) { - longs = static_cast(gc->alloc(sizeof(long))); - longs++; - } */ - Node *root = static_cast(gc.alloc(sizeof(Node))); - root = test_chain(3, false); - Node *root_child = root->child; - std::cout << "Adress of root:\t" << &root << std::endl; - std::cout << "Root points to:\t" << root << std::endl; - std::cout << "Root child:\t" << root_child << std::endl; - std::cout << "Root child, child:\t" << root_child->child << std::endl; + Node *root1 = static_cast(gc.alloc(sizeof(Node))); + //Node *root2 = static_cast(gc.alloc(sizeof(Node))); + root1 = test_chain(60000, false); + //root2 = test_chain(50000, true); gc.collect(GC::COLLECT_ALL); - gc.print_contents(); - - gc.dispose(); + auto end = std::chrono::high_resolution_clock::now(); + //std::cout << "Value of end: " << end.time_since_epoch().count() << std::endl; + + gc.print_summary(); + //gc.dispose(); + + std::cout + << "Execution time: " + << std::chrono::duration_cast(end - start).count() << " ≈ " + << (end - start) / 1ms << "ms ≈ " + << (end - start) / 1s << "s.\n"; + return 0; } \ No newline at end of file