Bug fix for superslab meta-data (#302)

* Replace time measuring macro

The DO_TIME macro was used originally to get performance numbers. The
macro makes tests hard to debug. This commit replaces it with a proper
C++ class with destructor.

* Bug fix

If the superslab meta data is large, then the calculation for the
sizeclasses that could use the short slab was incorrect.  This fixes
that calculation.

Co-authored-by: Nathaniel Wesley Filardo <nfilardo@microsoft.com>
This commit is contained in:
Matthew Parkinson
2021-03-23 12:42:11 +00:00
committed by GitHub
parent 04a185e634
commit 63f231f484
7 changed files with 91 additions and 57 deletions

View File

@@ -3,12 +3,19 @@
#include <chrono>
#include <iomanip>
#include <iostream>
#include <sstream>
#define DO_TIME(name, code) \
{ \
auto start__ = std::chrono::high_resolution_clock::now(); \
code auto finish__ = std::chrono::high_resolution_clock::now(); \
auto diff__ = finish__ - start__; \
std::cout << name << ": " << std::setw(12) << diff__.count() << " ns" \
<< std::endl; \
class MeasureTime : public std::stringstream
{
std::chrono::time_point<std::chrono::high_resolution_clock> start =
std::chrono::high_resolution_clock::now();
public:
~MeasureTime()
{
auto finish = std::chrono::high_resolution_clock::now();
auto diff = finish - start;
std::cout << str() << ": " << std::setw(12) << diff.count() << " ns"
<< std::endl;
}
};

View File

@@ -1,4 +1,3 @@
#include "test/measuretime.h"
#include "test/opt.h"
#include "test/setup.h"
#include "test/usage.h"

View File

@@ -64,7 +64,9 @@ namespace test
#endif
setup(r, alloc);
DO_TIME("External pointer queries ", {
{
MeasureTime m;
m << "External pointer queries ";
for (size_t i = 0; i < iterations; i++)
{
size_t rand = (size_t)r.next();
@@ -77,7 +79,7 @@ namespace test
if (calced_external != external_ptr)
abort();
}
});
}
teardown(alloc);
}

View File

@@ -1,6 +1,5 @@
#include <iostream>
#include <snmalloc.h>
#include <test/measuretime.h>
#include <test/opt.h>
#include <test/setup.h>
#include <unordered_set>

View File

@@ -10,54 +10,55 @@ void test_alloc_dealloc(size_t count, size_t size, bool write)
{
auto* alloc = ThreadAlloc::get();
DO_TIME(
"Count: " << std::setw(6) << count << ", Size: " << std::setw(6) << size
<< ", ZeroMem: " << (zero_mem == YesZero) << ", Write: " << write,
{
MeasureTime m;
m << "Count: " << std::setw(6) << count << ", Size: " << std::setw(6)
<< size << ", ZeroMem: " << (zero_mem == YesZero) << ", Write: " << write;
std::unordered_set<void*> set;
// alloc 1.5x objects
for (size_t i = 0; i < ((count * 3) / 2); i++)
{
std::unordered_set<void*> set;
void* p = alloc->alloc<zero_mem>(size);
SNMALLOC_CHECK(set.find(p) == set.end());
// alloc 1.5x objects
for (size_t i = 0; i < ((count * 3) / 2); i++)
{
void* p = alloc->alloc<zero_mem>(size);
SNMALLOC_CHECK(set.find(p) == set.end());
if (write)
*(int*)p = 4;
if (write)
*(int*)p = 4;
set.insert(p);
}
set.insert(p);
}
// free 0.25x of the objects
for (size_t i = 0; i < (count / 4); i++)
{
auto it = set.begin();
void* p = *it;
alloc->dealloc(p, size);
set.erase(it);
SNMALLOC_CHECK(set.find(p) == set.end());
}
// free 0.25x of the objects
for (size_t i = 0; i < (count / 4); i++)
{
auto it = set.begin();
void* p = *it;
alloc->dealloc(p, size);
set.erase(it);
SNMALLOC_CHECK(set.find(p) == set.end());
}
// alloc 1x objects
for (size_t i = 0; i < count; i++)
{
void* p = alloc->alloc<zero_mem>(size);
SNMALLOC_CHECK(set.find(p) == set.end());
// alloc 1x objects
for (size_t i = 0; i < count; i++)
{
void* p = alloc->alloc<zero_mem>(size);
SNMALLOC_CHECK(set.find(p) == set.end());
if (write)
*(int*)p = 4;
if (write)
*(int*)p = 4;
set.insert(p);
}
set.insert(p);
}
// free everything
while (!set.empty())
{
auto it = set.begin();
alloc->dealloc(*it, size);
set.erase(it);
}
});
// free everything
while (!set.empty())
{
auto it = set.begin();
alloc->dealloc(*it, size);
set.erase(it);
}
}
current_alloc_pool()->debug_check_empty();
}