Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
// auto obj = new ObjectA();
auto obj = boost::fast_pool_allocator<ObjectA>::allocate();
...
// delete *jj;
boost::fast_pool_allocator<ObjectA>::deallocate(*jj);
void func()
{
boost::object_pool<X> p;
for (int i = 0; i < 10000; ++i)
{
X * const t = p.malloc();
... // Do something with t; don't take the time to free() it.
}
} // on function exit, p is destroyed, and all destructors for the X objects are called.
auto index = curAtomicIndex_++;
uint32_t blocksCount = index >> 32;
uint32_t lastIndexInBlock = index & 0xffffffff;
Про переполнение счётчика тоже не понял. Если после инкремента выясняется, что блок закончился, то нужно выделять новый внутри классической критической секции (с повторной проверкой внутри критической секции). А если есть вероятность, что переполнится 32-бит счётчик (что невероятно, так как нужно иметь порядка 2^32 потоков), то нужно ещё раз проверять счётчик на переполнение ДО инкремента.
index = curAtomicIndex_++;
lock xadd QWORD PTR [rcx+32], r8.
Так что атомарность есть. index = curAtomicIndex_++;
в любом случае работает атомарно.в любом случае работает атомарно.
lock xadd QWORD PTR [rcx+32], r8.
$again$158:
; 2424 : again:
; 2425 : mov ecx, edx;
mov ecx, edx
; 2426 : mov ebx, eax;
mov ebx, eax
; 2427 : add ebx, dword ptr _Value;
add ebx, DWORD PTR $T7[ebp]
; 2428 : adc ecx, dword ptr _Value[4];
adc ecx, DWORD PTR $T7[ebp+4]
; 2429 : lock cmpxchg8b [esi];
lock cmpxchg8b QWORD PTR [esi]
; 2430 : jnz again;
jne SHORT $again$158
Во-первых, при ожидании имеет смысл не yield сразу вызывать, а раз от 5..30 цикл с проверкой прокрутить, так как современных процессорах велика вероятность, что другой поток исполняется на отдельном ядре. А Yield очень тяжёлая и длительная операция. Процентов 15% можно прироста скорости получить.
Одним махом 100 миллионов убивахом. Или lock-free распределитель памяти