This project should be written highly speedy and customizable.
This is why I really need nearly every milli second of execution time I can save.
Because of this I tend to use many news/deletes to not copy the objects themselves nor execute any kind of copy constructor.
To not overcall new/delete (because requesting Memory takes a huge time) I am saving already allocated memory in an internal pool of memory so I can reuse it later on.
I have got a class called "AllocationHelper", which contains some functions looking like the following one:
PHP Code:
std::vector<void*>* AllocationHelper::allocateVoidVector()
{
std::vector<void*>* ptr;
if(!allocatedVoidVectors.empty())
{
ptr=allocatedVoidVectors.back();
allocatedVoidVectors.pop_back();
}
else
{
ptr=new std::vector<void*>;
}
return ptr;
}
void AllocationHelper::recycleVoidVector(std::vector<void*>* ptr)
{
if(allocatedVoidVectors.size()<maximumPreAllocs)
{
ptr->clear();
allocatedVoidVectors.push_back(ptr);
return;
}
delete ptr;
}
This code runs quite fast but when I searched for some bottlenecks in my program I stumbled over some quite strange behavior.
If I write my functions above like this:
PHP Code:
__attribute__((noinline)) std::vector<void*>* AllocationHelper::_allocateVoidVector()
{
std::vector<void*>* ptr;
ptr=new std::vector<void*>;
return ptr;
}
std::vector<void*>* AllocationHelper::allocateVoidVector()
{
std::vector<void*>* ptr;
if(!allocatedVoidVectors.empty())
{
ptr=allocatedVoidVectors.back();
allocatedVoidVectors.pop_back();
}
else
{
ptr=_allocateVoidVector();
}
return ptr;
}
void AllocationHelper::recycleVoidVector(std::vector<void*>* ptr)
{
if(allocatedVoidVectors.size()<maximumPreAllocs)
{
ptr->clear();
allocatedVoidVectors.push_back(ptr);
return;
}
delete ptr;
}
I could not believe that my code is working correctly, so I tested all with std::cout to see what my program is doing and it worked like I wanted it to work:
It calls like 10 times the "new" operator and then calls around 1.000.000 times the push/pop operations.
If I remove this extern call to "_allocateVoidVector()" and insert the new in the if my code takes around 150ms for 1.000.000 iterations.
If I add this extern call and add "__attribute__((noinline))" (so gcc will not inline it) my code runs in 80ms.
This made me think about if the new is kind a called/prepared even if I not reach the else branch. After thinking and googling a while (without any results), I tried the exactly same code but this time used malloc:
PHP Code:
std::vector<void*>* AllocationHelper::allocateVoidVector()
{
std::vector<void*>* ptr;
if(!allocatedVoidVectors.empty())
{
ptr=allocatedVoidVectors.back();
allocatedVoidVectors.pop_back();
}
else
{
ptr=malloc(sizeof(std::vector<void*>));
ptr->setUp();
}
return ptr;
}
void AllocationHelper::recycleVoidVector(std::vector<void*>* ptr)
{
if(allocatedVoidVectors.size()<maximumPreAllocs)
{
ptr->clear();
allocatedVoidVectors.push_back(ptr);
return;
}
ptr->destroy();
free(ptr);
}
So my question is not really a question but more kind of:
Quote:
Did you ever encouter something similar (I am using MinGW with gcc 5.1.0)?
What do you suggest how should I solve this problem? Should I use extra functions (which also slows down a bit, but not too much) or should I use some kind of bad practice by allocating class objects with malloc?






