diff --git a/drama/src/rev-mc.c b/drama/src/rev-mc.c index 4c765a9..3471d0f 100644 --- a/drama/src/rev-mc.c +++ b/drama/src/rev-mc.c @@ -10,9 +10,14 @@ #include #include +#include #include +#include #include +#include +#include #include +#include #include #include "rev-mc.h" @@ -295,29 +300,51 @@ find_row_mask(std::vector &sets, } } - uint64_t row_mask = LS_BITMASK(16);// use 16 bits for the row - uint64_t last_mask = (row_mask << (40 - 16)); + uint64_t row_mask = LS_BITMASK(16);// use 16 bits for the row + const uint64_t last_mask = (row_mask << (40 - 16)); row_mask <<= CL_SHIFT;// skip the lowest 6 bits since they're used for CL addressing - while (row_mask < last_mask) { - uint64_t next_row_mask = next_bit_permutation(row_mask); - if (row_mask & LS_BITMASK(CL_SHIFT)) { - row_mask = next_row_mask; - continue; - } - + auto resolve = [=](uint64_t row_mask) -> bool { + if (row_mask & LS_BITMASK(CL_SHIFT)) { return false; } for (auto addr_pool : same_row_sets) { addr_tuple base_addr = addr_pool[0]; for (int i = 1; i < addr_pool.size(); i++) { addr_tuple tmp = addr_pool[i]; - if ((tmp.p_addr & row_mask) != (base_addr.p_addr & row_mask)) { goto next_mask; } + if ((tmp.p_addr & row_mask) != (base_addr.p_addr & row_mask)) { return false; } } } + return true; + }; - break; + std::atomic_bool found{false}; + std::mutex lock; + std::queue mask_task; - next_mask: - row_mask = next_row_mask; + while (row_mask < last_mask) { + mask_task.push(row_mask); + row_mask = next_bit_permutation(row_mask); + } + + std::vector worker; + for (int i = 0; i < 8; ++i) { + worker.emplace_back([&] { + while (!found) { + uint64_t cur_mask; + { + std::lock_guard _(lock); + if (mask_task.empty()) { break; } + cur_mask = mask_task.front(); + mask_task.pop(); + } + + if (resolve(cur_mask)) { + std::lock_guard _(lock); + found.store(true); + row_mask = cur_mask; + while (!mask_task.empty()) mask_task.pop(); + } + } + }); } // super hackish way to recover the real row mask