История изменений
Исправление
kilokolyan,
(текущая версия)
:
И я теперь ну совсем не понимаю зачем Вы хотите свой memory manager (и тем более работающий с fixed-size blocks)
Потому что брать готовые pointers на 4кб/8кб/1мб куски памяти быстрее в 2…4 раза, чем дёргать malloc() на рандомные размеры. Так мерял:
int test_malloc() {
auto NUM = 1024 * 1024;
std::vector<char*> stack_free(NUM, nullptr);
std::vector<char*> stack_alloc;
stack_alloc.reserve(NUM);
for (int i = 0; i < NUM; ++i) {
stack_free[i] = new char[4096];
}
size_t cnt_allocated = 0;
{
Measure me("malloc");
for (int i = 0; i < NUM; ++i) {
// sz is for malloc argument AND to touch memory at position "sz/2";
static const auto minimum = 1024;
// increasing "minimum" gives slower results
int sz = minimum + (rand() % (4096 - minimum));
// you can change malloc arg to constant "4096" and measure: you will get SLOWER results
char *ptr = reinterpret_cast<char*>(malloc(sz));
stack_alloc.push_back(ptr);
ptr[sz / 2] = sz;
}
}
// prepare alloc-vector for new allocations.
// memory leak, yes:
stack_alloc.clear();
{
Measure me("slab");
for (int i = 0; i < NUM; ++i) {
int sz = 1024 + (rand() % (4096 - 1024));
char *ptr = stack_free.back();
stack_free.pop_back();
stack_alloc.push_back(ptr);
// touch memory; also for measuring rand() in this loop too
ptr[sz / 2] = sz;
}
}
return 0;
}
Исправление
kilokolyan,
:
И я теперь ну совсем не понимаю зачем Вы хотите свой memory manager (и тем более работающий с fixed-size blocks)
Потому что брать готовые pointers на 4кб/8кб/1мб куски памяти быстрее в 2…4 раза, чем дёргать malloc() на рандомные размеры. Так мерял:
int test_malloc() {
auto NUM = 1024 * 1024;
std::vector<char*> stack_free(NUM, nullptr);
std::vector<char*> stack_alloc;
stack_alloc.reserve(NUM);
for (int i = 0; i < NUM; ++i) {
stack_free[i] = new char[4096];
}
size_t cnt_allocated = 0;
{
Measure me("malloc");
for (int i = 0; i < NUM; ++i) {
// sz is for malloc argument AND to touch memory at position "sz/2";
static const auto minimum = 256;
// increasing "minimum" gives slower results
int sz = minimum + (rand() % (4096 - minimum));
// you can change malloc arg to constant "4096" and measure: you will get SLOWER results
char *ptr = reinterpret_cast<char*>(malloc(sz));
stack_alloc.push_back(ptr);
ptr[sz / 2] = sz;
}
}
// prepare alloc-vector for new allocations.
// memory leak, yes:
stack_alloc.clear();
{
Measure me("slab");
for (int i = 0; i < NUM; ++i) {
int sz = 1024 + (rand() % (4096 - 1024));
char *ptr = stack_free.back();
stack_free.pop_back();
stack_alloc.push_back(ptr);
// touch memory; also for measuring rand() in this loop too
ptr[sz / 2] = sz;
}
}
return 0;
}
Исходная версия
kilokolyan,
:
И я теперь ну совсем не понимаю зачем Вы хотите свой memory manager (и тем более работающий с fixed-size blocks)
Потому что брать готовые pointers на 4кб/8кб/1мб куски памяти быстрее в 2…3 раза, чем дёргать malloc() на рандомные размеры. Так мерял:
int test_malloc() {
auto NUM = 1024 * 1024;
std::vector<char*> stack_free(NUM, nullptr);
std::vector<char*> stack_alloc;
stack_alloc.reserve(NUM);
for (int i = 0; i < NUM; ++i) {
stack_free[i] = new char[4096];
}
size_t cnt_allocated = 0;
{
Measure me("malloc");
for (int i = 0; i < NUM; ++i) {
// sz is for malloc argument AND to touch memory at position "sz/2";
static const auto minimum = 256;
// increasing "minimum" gives slower results
int sz = minimum + (rand() % (4096 - minimum));
// you can change malloc arg to constant "4096" and measure: you will get SLOWER results
char *ptr = reinterpret_cast<char*>(malloc(sz));
stack_alloc.push_back(ptr);
ptr[sz / 2] = sz;
}
}
{
Measure me("slab");
for (int i = 0; i < NUM; ++i) {
int sz = 1024 + (rand() % (4096 - 1024));
char *ptr = stack_free.back();
stack_free.pop_back();
stack_alloc.push_back(ptr);
// touch memory; also for measuring rand() in this loop too
ptr[sz / 2] = sz;
}
}
return 0;
}