Files
snmalloc/src/test/perf/startup/startup.cc
Matthew Parkinson 5f7baef755 Refactor: Remove unused features and functions, and move most allocator operations to a global namespace. (#750)
* Factor out explicit Config type

Instead of using snmalloc::Alloc::Config, expose snmalloc::Config, which is then used to derive the allocator type.

* Move globalalloc to front end.

* Remove unneed template parameter from global snmalloc functions.

* Remove SNMALLOC_PASS_THROUGH

VeronaRT now has an abstraction layer which can easily replace the allocator.
Having such a complex integration still in snmalloc does not make sense.

* Take some global functions off of local alloc.

* Drop comparison overloads on atomic Capptr.

Performing a comparison on two atomic ptr is a complex operation, and should not be implicit.  The memory model order and such things needs to be considered by the caller.

* Remove function_ref and use templates

The implementation prefers to use templates over the function_ref.  This now only exists in the Pal for a currently unused feature.

* Removing function_ref reduces stl needs.

* Remove use of __is_convertible to support older g++

* Inline function that is only used once.

* Remove unused function

* Restrict ThreadAlloc usage to globalalloc

This commit introduces various inline functions on snmalloc:: that perform allocation/deallocation using the thread local allocator.

They remove all usage from a particular test.

* Move cheri checks to own file.

* Refactor is_owned checks.

* Move alloc_size and check_size to globalalloc.

* Minor simplification of dealloc path

* Fix up is_owned to take a config

* Improve usage of scoped allocator.

* Handle Config_ in globalalloc.
2025-02-22 19:53:27 +00:00

95 lines
1.8 KiB
C++

#include "test/opt.h"
#include "test/setup.h"
#include "test/usage.h"
#include "test/xoroshiro.h"
#include <algorithm>
#include <iostream>
#include <snmalloc/snmalloc.h>
#include <thread>
#include <vector>
using namespace snmalloc;
std::vector<uint64_t> counters{};
template<typename F>
class ParallelTest
{
private:
std::atomic<bool> flag = false;
std::atomic<size_t> ready = 0;
uint64_t start;
uint64_t end;
std::atomic<size_t> complete = 0;
size_t cores;
F f;
void run(size_t id)
{
auto prev = ready.fetch_add(1);
if (prev + 1 == cores)
{
start = Aal::tick();
flag = true;
}
while (!flag)
Aal::pause();
f(id);
prev = complete.fetch_add(1);
if (prev + 1 == cores)
{
end = Aal::tick();
}
}
public:
ParallelTest(F&& f, size_t cores) : cores(cores), f(std::forward<F>(f))
{
std::thread* t = new std::thread[cores];
for (size_t i = 0; i < cores; i++)
{
t[i] = std::thread(&ParallelTest::run, this, i);
}
// Wait for all the threads.
for (size_t i = 0; i < cores; i++)
{
t[i].join();
}
delete[] t;
}
uint64_t time()
{
return end - start;
}
};
int main()
{
auto nthreads = std::thread::hardware_concurrency();
counters.resize(nthreads);
ParallelTest test(
[](size_t id) {
auto start = Aal::tick();
snmalloc::dealloc(snmalloc::alloc(1));
auto end = Aal::tick();
counters[id] = end - start;
},
nthreads);
std::cout << "Taken: " << test.time() << std::endl;
std::sort(counters.begin(), counters.end());
uint64_t start = 0;
for (auto counter : counters)
{
std::cout << "Thread time " << counter << " (" << counter - start << ")"
<< std::endl;
start = counter;
}
}