Skip to content

Commit

Permalink
avoid false sharing??
Browse files Browse the repository at this point in the history
  • Loading branch information
VinInn committed May 10, 2022
1 parent 8b149ed commit 5866970
Showing 1 changed file with 21 additions and 18 deletions.
39 changes: 21 additions & 18 deletions HeterogeneousCore/CUDAUtilities/interface/SimplePoolAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class SimplePoolAllocator {

SimplePoolAllocator(int maxSlots) : m_maxSlots(maxSlots) {
for (auto &p : m_used)
p = true;
p.v = true;
}

int size() const { return m_size; }
Expand All @@ -48,7 +48,7 @@ class SimplePoolAllocator {

void free(int i) {
m_last[i] = -1;
m_used[i] = false;
m_used[i].v = false;
}

int alloc(uint64_t s) {
Expand All @@ -58,7 +58,7 @@ class SimplePoolAllocator {
// if(totBytes>4507964512) garbageCollect();

if (i >= 0) {
assert(m_used[i]);
assert(m_used[i].v);
if (nullptr == m_slots[i])
std::cout << "race ??? " << i << ' ' << m_bucket[i] << ' ' << m_last[i] << std::endl;
assert(m_slots[i]);
Expand All @@ -67,7 +67,7 @@ class SimplePoolAllocator {
garbageCollect();
i = allocImpl(s);
if (i >= 0) {
assert(m_used[i]);
assert(m_used[i].v);
assert(m_slots[i]);
assert(m_last[i] >= 0);
}
Expand All @@ -82,14 +82,14 @@ class SimplePoolAllocator {
for (int i = 0; i < ls; ++i) {
if (b != m_bucket[i])
continue;
if (m_used[i])
if (m_used[i].v)
continue;
bool exp = false;
if (m_used[i].compare_exchange_strong(exp, true)) {
if (m_used[i].v.compare_exchange_strong(exp, true)) {
// verify if in the mean time the garbage collector did operate
if (nullptr == m_slots[i]) {
assert(m_bucket[i] < 0);
m_used[i] = false;
m_used[i].v = false;
continue;
}
m_last[i] = 0;
Expand All @@ -113,7 +113,7 @@ class SimplePoolAllocator {
}

int createAt(int ls, int b) {
assert(m_used[ls]);
assert(m_used[ls].v);
assert(m_last[ls] > 0);
m_bucket[ls] = b;
auto as = poolDetails::bucketSize(b);
Expand All @@ -129,14 +129,14 @@ class SimplePoolAllocator {
void garbageCollect() {
int ls = size();
for (int i = 0; i < ls; ++i) {
if (m_used[i])
if (m_used[i].v)
continue;
if (m_bucket[i] < 0)
continue;
bool exp = false;
if (!m_used[i].compare_exchange_strong(exp, true))
if (!m_used[i].v.compare_exchange_strong(exp, true))
continue;
assert(m_used[i]);
assert(m_used[i].v);
if (nullptr != m_slots[i]) {
assert(m_bucket[i] >= 0);
doFree(m_slots[i]);
Expand All @@ -146,7 +146,7 @@ class SimplePoolAllocator {
m_slots[i] = nullptr;
m_bucket[i] = -1;
m_last[i] = -3;
m_used[i] = false; // here memory fence as well
m_used[i].v = false; // here memory fence as well
}
}

Expand All @@ -155,18 +155,18 @@ class SimplePoolAllocator {
for (int i = 0; i < ls; ++i) {
if (m_bucket[i] >= 0)
continue;
if (m_used[i])
if (m_used[i].v)
continue;
bool exp = false;
if (!m_used[i].compare_exchange_strong(exp, true))
if (!m_used[i].v.compare_exchange_strong(exp, true))
continue;
if (nullptr != m_slots[i]) { // ops allocated and freed
assert(m_bucket[i] >= 0);
assert(m_last[i] = -1);
m_used[i] = false;
m_used[i].v = false;
continue;
}
assert(m_used[i]);
assert(m_used[i].v);
m_last[i] = 1;
return createAt(i, b);
}
Expand All @@ -178,7 +178,7 @@ class SimplePoolAllocator {
uint64_t fs = 0;
int ls = size();
for (int i = 0; i < ls; ++i) {
if (m_used[i]) {
if (m_used[i].v) {
auto b = m_bucket[i];
if (b < 0)
continue;
Expand All @@ -201,7 +201,10 @@ class SimplePoolAllocator {

std::vector<int> m_bucket = std::vector<int>(m_maxSlots, -1);
std::vector<Pointer> m_slots = std::vector<Pointer>(m_maxSlots, nullptr);
std::vector<std::atomic<bool>> m_used = std::vector<std::atomic<bool>>(m_maxSlots);
struct alBool {
alignas(64) std::atomic<bool> v;
};
std::vector<alBool> m_used = std::vector<alBool>(m_maxSlots);
std::atomic<int> m_size = 0;

std::atomic<uint64_t> totBytes = 0;
Expand Down

0 comments on commit 5866970

Please sign in to comment.