Skip to content

Commit 5073209

Browse files
committed
shm: implement first fit for header allocation
1 parent e080fb6 commit 5073209

File tree

2 files changed

+48
-13
lines changed

2 files changed

+48
-13
lines changed

src/common/MemoryUtils.h

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,11 @@ static constexpr const char *ENV_NOLOCK = "DATADIST_NO_MLOCK";
5353
static constexpr const char *ENV_SHM_PATH = "DATADIST_SHM_PATH";
5454
static constexpr const char *ENV_SHM_DELAY = "DATADIST_SHM_DELAY";
5555

56+
enum RegionAllocStrategy {
57+
eFindLongest,
58+
eFindFirst
59+
};
60+
5661
template<size_t ALIGN = 64>
5762
class RegionAllocatorResource
5863
{
@@ -61,8 +66,10 @@ class RegionAllocatorResource
6166
RegionAllocatorResource() = delete;
6267

6368
RegionAllocatorResource(std::string pSegmentName, FairMQTransportFactory& pShmTrans,
64-
std::size_t pSize, std::uint64_t pRegionFlags = 0, bool pCanFail = false)
69+
std::size_t pSize, const RegionAllocStrategy pStrategy, std::uint64_t pRegionFlags = 0,
70+
bool pCanFail = false)
6571
: mSegmentName(pSegmentName),
72+
mStrategy(pStrategy),
6673
mCanFail(pCanFail),
6774
mTransport(pShmTrans)
6875
{
@@ -379,31 +386,47 @@ class RegionAllocatorResource
379386
return false;
380387
}
381388

382-
auto lMaxIter = std::max_element(std::begin(mFreeRanges), std::end(mFreeRanges),
383-
[](const auto& l, const auto& r) {
384-
return (l.first.upper() - l.first.lower()) < (r.first.upper() - r.first.lower());
385-
});
389+
auto lMaxIter = mFreeRanges.end();
390+
391+
if (mStrategy == eFindFirst) {
392+
for (auto lInt = mFreeRanges.begin(); lInt != mFreeRanges.end(); ++lInt) {
393+
if (lInt->first.upper() - lInt->first.lower() >= pSize) {
394+
lMaxIter = lInt;
395+
break;
396+
}
397+
}
398+
} else { /* eFindLongest */
399+
lMaxIter = std::max_element(mFreeRanges.begin(), mFreeRanges.end(),
400+
[](const auto& l, const auto& r) {
401+
return (l.first.upper() - l.first.lower()) < (r.first.upper() - r.first.lower());
402+
}
403+
);
404+
}
405+
406+
if (lMaxIter == mFreeRanges.end()) {
407+
return false;
408+
}
386409

387410
// check if the size is adequate
388-
const auto lFoudSize = lMaxIter->first.upper() - lMaxIter->first.lower();
389-
if (pSize > lFoudSize) {
411+
const auto lFoundSize = lMaxIter->first.upper() - lMaxIter->first.lower();
412+
if (pSize > lFoundSize) {
390413
return false;
391414
}
392415

393416
if (lMaxIter->second > 1) {
394417
EDDLOG("RegionAllocator BUG: Overlapping interval found: ptr={:p} length={} overlaps={}",
395-
reinterpret_cast<char*>(lMaxIter->first.lower()), lFoudSize, lMaxIter->second);
418+
reinterpret_cast<char*>(lMaxIter->first.lower()), lFoundSize, lMaxIter->second);
396419

397420
// erase this segment
398-
mFree -= lFoudSize;
421+
mFree -= lFoundSize;
399422
assert (mFree > 0);
400423
mFreeRanges.erase(lMaxIter);
401424
return false;
402425
}
403426

404427
// return the extent
405428
mStart = reinterpret_cast<char*>(lMaxIter->first.lower());
406-
mLength = lFoudSize;
429+
mLength = lFoundSize;
407430
mFreeRanges.erase(lMaxIter);
408431

409432
{
@@ -448,6 +471,7 @@ class RegionAllocatorResource
448471
std::string mSegmentName;
449472
std::size_t mSegmentSize;
450473
std::atomic_bool mRunning = false;
474+
RegionAllocStrategy mStrategy;
451475
bool mCanFail = false;
452476

453477
FairMQTransportFactory &mTransport;

src/common/SubTimeFrameBuilder.cxx

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ SubTimeFrameReadoutBuilder::SubTimeFrameReadoutBuilder(MemoryResources &pMemRes,
3939
"O2HeadersRegion",
4040
*mMemRes.mShmTransport,
4141
std::size_t(512) << 20, /* good for 5s 3CRU @ 50Gbps, TODO: make configurable */
42+
RegionAllocStrategy::eFindFirst,
4243
0, /* region flags ? */
4344
true /* Header alloc can fail with large FLP-DPL backpreassure */
4445
);
@@ -305,13 +306,16 @@ SubTimeFrameFileBuilder::SubTimeFrameFileBuilder(MemoryResources &pMemRes,
305306
"O2HeadersRegion_FileSource",
306307
*mMemRes.mShmTransport,
307308
pHdrSegSize,
308-
0
309+
RegionAllocStrategy::eFindFirst,
310+
0, /* GPU flags */
311+
false /* cannot fail */
309312
);
310313

311314
mMemRes.mDataMemRes = std::make_unique<RegionAllocatorResource<>>(
312315
"O2DataRegion_FileSource",
313316
*mMemRes.mShmTransport,
314317
pDataSegSize,
318+
RegionAllocStrategy::eFindLongest,
315319
0 // TODO: GPU flags
316320
);
317321

@@ -385,14 +389,18 @@ void TimeFrameBuilder::allocate_memory(const std::size_t pDataSegSize, const std
385389
"O2HeadersRegion",
386390
*mMemRes.mShmTransport,
387391
pHdrSegSize,
388-
0 /* dont need registration flags for headers */
392+
RegionAllocStrategy::eFindFirst,
393+
0, /* GPU flags */
394+
false /* cannot fail */
389395
);
390396

391397
mMemRes.mDataMemRes = std::make_unique<RegionAllocatorResource<>>(
392398
"O2DataRegion_TimeFrame",
393399
*mMemRes.mShmTransport,
394400
pDataSegSize,
395-
0 // TODO: GPU flags
401+
RegionAllocStrategy::eFindLongest,
402+
0, /* TODO: GPU flags */
403+
false /* cannot fail */
396404
);
397405

398406
mMemRes.start();
@@ -450,6 +458,9 @@ void TimeFrameBuilder::adaptHeaders(SubTimeFrame *pStf)
450458
o2::framework::DataProcessingHeader{pStf->header().mId}
451459
);
452460

461+
WDDLOG_RL(5000, "Reallocation of Header messages is not optimal. orig_size={} new_size={}",
462+
lHeader->GetSize(), lStack.size());
463+
453464
lStfDataIter.mHeader = newHeaderMessage(reinterpret_cast<char*>(lStack.data()), lStack.size());
454465
if (!lStfDataIter.mHeader) {
455466
return;

0 commit comments

Comments
 (0)