Changeset 26420 in vbox
- Timestamp:
- Feb 11, 2010 2:55:04 AM (15 years ago)
- Location:
- trunk/src/VBox/Runtime
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/common/alloc/memcache.cpp
r26419 r26420 71 71 * without taking any locks. */ 72 72 PRTMEMCACHEPAGE volatile pNext; 73 /** The number of free objects. */74 int32_t volatile cFree;75 /** The number of objects on this page. */76 uint32_t cObjects;77 73 /** Bitmap tracking allocated blocks. */ 78 74 void volatile *pbmAlloc; … … 81 77 /** Pointer to the object array.. */ 82 78 uint8_t *pbObjects; 79 /** The number of objects on this page. */ 80 uint32_t cObjects; 81 82 /** Padding to force cFree into the next cache line. (ASSUMES CL = 64) */ 83 uint8_t abPadding[ARCH_BITS == 32 ? 64 - 6*4 : 64 - 5*8 - 4]; 84 /** The number of free objects. */ 85 int32_t volatile cFree; 83 86 } RTMEMCACHEPAGE; 87 AssertCompileMemberOffset(RTMEMCACHEPAGE, cFree, 64); 84 88 85 89 … … 103 107 /** The maximum number of objects. */ 104 108 uint32_t cMax; 105 /** The total object count. */106 uint32_t volatile cTotal;107 /** The number of free objects. */108 int32_t volatile cFree;109 109 /** Head of the page list. */ 110 110 PRTMEMCACHEPAGE pPageHead; 111 /** This may point to a page with free entries. */112 PRTMEMCACHEPAGE volatile pPageHint;113 111 /** Constructor callback. */ 114 112 PFNMEMCACHECTOR pfnCtor; … … 119 117 /** Critical section serializing page allocation and similar. */ 120 118 RTCRITSECT CritSect; 119 120 /** The total object count. */ 121 uint32_t volatile cTotal; 122 /** The number of free objects. */ 123 int32_t volatile cFree; 124 /** This may point to a page with free entries. */ 125 PRTMEMCACHEPAGE volatile pPageHint; 121 126 } RTMEMCACHEINT; 122 127 … … 161 166 pThis->cbAlignment = cbAlignment; 162 167 pThis->cPerPage = (PAGE_SIZE - RT_ALIGN_Z(sizeof(RTMEMCACHEPAGE), cbAlignment)) / pThis->cbObject; 163 while ( RT_ALIGN_Z(sizeof(RTMEMCACHEPAGE), cbAlignment)168 while ( RT_ALIGN_Z(sizeof(RTMEMCACHEPAGE), RT_MIN(cbAlignment, 8)) 164 169 + pThis->cPerPage * pThis->cbObject 165 + RT_ALIGN(pThis->cPerPage, 32)* 2170 + RT_ALIGN(pThis->cPerPage, 64) / 8 * 2 166 171 > PAGE_SIZE) 167 172 pThis->cPerPage--; 168 pThis->cBits = RT_ALIGN(pThis->cPerPage, 32);173 pThis->cBits = RT_ALIGN(pThis->cPerPage, 64); 169 174 pThis->cMax = cMaxObjects; 170 175 pThis->cTotal = 0; … … 236 241 /* 237 242 * Allocate and initialize the new page. 243 * 244 * We put the constructor bitmap at the lower end right after cFree. 245 * We then push the object array to the end of the page and place the 246 * allocation bitmap below it. The hope is to increase the chance that 247 * the allocation bitmap is in a different cache line than cFree since 248 * this increases performance markably when lots of threads are beating 249 * on the cache. 238 250 */ 239 251 PRTMEMCACHEPAGE pPage = (PRTMEMCACHEPAGE)RTMemPageAlloc(PAGE_SIZE); … … 247 259 pPage->cFree = cObjects; 248 260 pPage->cObjects = cObjects; 249 pPage->pbmAlloc = pPage + 1; 250 pPage->pbmCtor = (uint8_t *)pPage->pbmAlloc + pThis->cBits / 8; 251 pPage->pbObjects = (uint8_t *)pPage->pbmCtor + pThis->cBits / 8; 252 pPage->pbObjects = RT_ALIGN_PT(pPage->pbObjects, pThis->cbAlignment, uint8_t *); 261 uint8_t *pb = (uint8_t *)(pPage + 1); 262 pb = RT_ALIGN_PT(pb, 8, uint8_t *); 263 pPage->pbmCtor = pb; 264 pb += pThis->cBits / 8 * 2; 265 pb = (uint8_t *)pPage + PAGE_SIZE - pThis->cbObject * cObjects; 266 pPage->pbObjects = pb; Assert(RT_ALIGN_P(pb, pThis->cbAlignment) == pb); 267 pb -= pThis->cBits / 8; 268 pb = (uint8_t *)((uintptr_t)pb & ~(uintptr_t)7); 269 pPage->pbmAlloc = pb; 270 Assert((uintptr_t)pPage->pbmCtor + pThis->cBits / 8 < (uintptr_t)pPage->pdmDtor); 253 271 254 272 /* Mark the bitmap padding and any unused objects as allocated. */ … … 309 327 */ 310 328 int32_t cNewFree = ASMAtomicDecS32(&pThis->cFree); 311 if ( cNewFree < 0)329 if (RT_LIKELY(cNewFree < 0)) 312 330 { 313 331 uint32_t cTotal = ASMAtomicUoReadU32(&pThis->cTotal); … … 364 382 { 365 383 iObj = ASMBitFirstClear(pPage->pbmAlloc, pThis->cBits); 366 if (iObj < 0) 384 if (RT_LIKELY(iObj >= 0)) 385 { 386 if (!ASMAtomicBitTestAndSet(pPage->pbmAlloc, iObj)) 387 break; 388 } 389 else 367 390 ASMMemoryFence(); 368 else if (!ASMAtomicBitTestAndSet(pPage->pbmAlloc, iObj))369 break;370 391 Assert(cLoops2 != 40); 371 392 } … … 424 445 */ 425 446 PRTMEMCACHEPAGE pPage = (PRTMEMCACHEPAGE)(((uintptr_t)pvObj) & ~(uintptr_t)PAGE_OFFSET_MASK); 426 Assert ReturnVoid(pPage->pCache == pThis);427 Assert ReturnVoid(ASMAtomicUoReadS32(&pPage->cFree) < (int32_t)pThis->cPerPage);447 Assert(pPage->pCache == pThis); 448 Assert(ASMAtomicUoReadS32(&pPage->cFree) < (int32_t)pThis->cPerPage); 428 449 429 450 /* … … 432 453 uintptr_t offObj = (uintptr_t)pvObj - (uintptr_t)pPage->pbObjects; 433 454 uintptr_t iObj = offObj / pThis->cbObject; 434 Assert ReturnVoid(iObj * pThis->cbObject == offObj);455 Assert(iObj * pThis->cbObject == offObj); 435 456 Assert(iObj < pThis->cPerPage); 436 457 AssertReturnVoid(ASMAtomicBitTestAndClear(pPage->pbmAlloc, iObj)); -
trunk/src/VBox/Runtime/testcase/tstRTMemCache.cpp
r26419 r26420 254 254 static void tst3(uint32_t cThreads, uint32_t cbObject, bool fUseCache, uint32_t cSecs) 255 255 { 256 RTTestISubF("Benchmark - %u threads, % s", cThreads, fUseCache ? "RTMemCache" : "RTMemAlloc");256 RTTestISubF("Benchmark - %u threads, %u bytes, %u secs, %s", cThreads, cbObject, cSecs, fUseCache ? "RTMemCache" : "RTMemAlloc"); 257 257 258 258 /* … … 300 300 cIterations += aThreads[i].cIterations; 301 301 302 RTTestIPrintf(RTTESTLVL_ALWAYS, "%'8u iterations per second\n", 303 (unsigned)((long double)cIterations * 1000000000.0 / cElapsedNS)); 302 RTTestIPrintf(RTTESTLVL_ALWAYS, "%'8u iterations per second, %'llu ns on avg\n", 303 (unsigned)((long double)cIterations * 1000000000.0 / cElapsedNS), 304 cElapsedNS / cIterations); 304 305 305 306 /* clean up */ … … 322 323 { 323 324 /* threads, cbObj, fUseCache, cSecs */ 325 tst3( 1, 256, true, 5); 326 tst3( 1, 256, false, 5); 324 327 tst3( 1, 32, true, 5); 325 328 tst3( 1, 32, false, 5); 326 329 tst3( 1, 8, true, 5); 330 tst3( 1, 8, false, 5); 331 tst3( 1, 2, true, 5); 332 tst3( 1, 2, false, 5); 333 tst3( 1, 1, true, 5); 334 tst3( 1, 1, false, 5); 335 336 tst3( 3, 256, true, 5); 337 tst3( 3, 256, false, 5); 338 tst3( 3, 128, true, 5); 339 tst3( 3, 128, false, 5); 340 tst3( 3, 64, true, 5); 341 tst3( 3, 64, false, 5); 327 342 tst3( 3, 32, true, 5); 328 343 tst3( 3, 32, false, 5); 344 tst3( 3, 2, true, 5); 345 tst3( 3, 2, false, 5); 346 tst3( 3, 1, true, 5); 347 tst3( 3, 1, false, 5); 329 348 330 349 tst3( 16, 32, true, 5);
Note:
See TracChangeset
for help on using the changeset viewer.