Add support for more than two XOR bits
This commit is contained in:
@@ -59,7 +59,8 @@ static void decode(benchmark::State& state)
|
||||
|
||||
for (auto _ : state)
|
||||
{
|
||||
auto decodedAddress = decoder.decodeAddress(distribution(engine));
|
||||
auto randomAddress = distribution(engine);
|
||||
auto decodedAddress = decoder.decodeAddress(randomAddress);
|
||||
benchmark::DoNotOptimize(decodedAddress);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -43,28 +43,21 @@
|
||||
namespace DRAMSys::Config
|
||||
{
|
||||
|
||||
struct XorPair
|
||||
{
|
||||
unsigned int FIRST;
|
||||
unsigned int SECOND;
|
||||
};
|
||||
|
||||
NLOHMANN_JSONIFY_ALL_THINGS(XorPair, FIRST, SECOND)
|
||||
|
||||
struct AddressMapping
|
||||
{
|
||||
static constexpr std::string_view KEY = "addressmapping";
|
||||
static constexpr std::string_view SUB_DIR = "addressmapping";
|
||||
|
||||
std::optional<std::vector<unsigned int>> BYTE_BIT;
|
||||
std::optional<std::vector<unsigned int>> COLUMN_BIT;
|
||||
std::optional<std::vector<unsigned int>> ROW_BIT;
|
||||
std::optional<std::vector<unsigned int>> BANK_BIT;
|
||||
std::optional<std::vector<unsigned int>> BANKGROUP_BIT;
|
||||
std::optional<std::vector<unsigned int>> RANK_BIT;
|
||||
std::optional<std::vector<unsigned int>> PSEUDOCHANNEL_BIT;
|
||||
std::optional<std::vector<unsigned int>> CHANNEL_BIT;
|
||||
std::optional<std::vector<XorPair>> XOR;
|
||||
using BitEntry = std::variant<unsigned int, std::vector<unsigned int>>;
|
||||
|
||||
std::optional<std::vector<BitEntry>> BYTE_BIT;
|
||||
std::optional<std::vector<BitEntry>> COLUMN_BIT;
|
||||
std::optional<std::vector<BitEntry>> ROW_BIT;
|
||||
std::optional<std::vector<BitEntry>> BANK_BIT;
|
||||
std::optional<std::vector<BitEntry>> BANKGROUP_BIT;
|
||||
std::optional<std::vector<BitEntry>> RANK_BIT;
|
||||
std::optional<std::vector<BitEntry>> PSEUDOCHANNEL_BIT;
|
||||
std::optional<std::vector<BitEntry>> CHANNEL_BIT;
|
||||
};
|
||||
|
||||
NLOHMANN_JSONIFY_ALL_THINGS(AddressMapping,
|
||||
@@ -75,8 +68,7 @@ NLOHMANN_JSONIFY_ALL_THINGS(AddressMapping,
|
||||
BANKGROUP_BIT,
|
||||
RANK_BIT,
|
||||
PSEUDOCHANNEL_BIT,
|
||||
CHANNEL_BIT,
|
||||
XOR)
|
||||
CHANNEL_BIT)
|
||||
|
||||
} // namespace DRAMSys::Config
|
||||
|
||||
|
||||
@@ -47,56 +47,71 @@
|
||||
namespace DRAMSys
|
||||
{
|
||||
|
||||
static void addMapping(std::vector<Config::AddressMapping::BitEntry> const& mappingVector,
|
||||
std::vector<unsigned>& bitVector,
|
||||
std::vector<std::vector<unsigned>>& xorVector)
|
||||
{
|
||||
for (const auto& bitEntry : mappingVector)
|
||||
{
|
||||
std::visit(
|
||||
[&bitVector, &xorVector](auto&& arg)
|
||||
{
|
||||
using T = std::decay_t<decltype(arg)>;
|
||||
if constexpr (std::is_same_v<T, unsigned>)
|
||||
{
|
||||
bitVector.push_back(arg);
|
||||
}
|
||||
else if constexpr (std::is_same_v<T, std::vector<unsigned>>)
|
||||
{
|
||||
bitVector.push_back(arg.at(0));
|
||||
xorVector.push_back(arg);
|
||||
}
|
||||
},
|
||||
bitEntry);
|
||||
}
|
||||
}
|
||||
|
||||
AddressDecoder::AddressDecoder(const DRAMSys::Config::AddressMapping& addressMapping)
|
||||
{
|
||||
if (const auto& channelBits = addressMapping.CHANNEL_BIT)
|
||||
{
|
||||
std::copy(channelBits->begin(), channelBits->end(), std::back_inserter(vChannelBits));
|
||||
addMapping(*channelBits, vChannelBits, vXor);
|
||||
}
|
||||
|
||||
if (const auto& rankBits = addressMapping.RANK_BIT)
|
||||
{
|
||||
std::copy(rankBits->begin(), rankBits->end(), std::back_inserter(vRankBits));
|
||||
addMapping(*rankBits, vRankBits, vXor);
|
||||
}
|
||||
|
||||
// HBM pseudo channels are internally modelled as ranks
|
||||
if (const auto& pseudoChannelBits = addressMapping.PSEUDOCHANNEL_BIT)
|
||||
{
|
||||
std::copy(
|
||||
pseudoChannelBits->begin(), pseudoChannelBits->end(), std::back_inserter(vRankBits));
|
||||
addMapping(*pseudoChannelBits, vRankBits, vXor);
|
||||
}
|
||||
|
||||
if (const auto& bankGroupBits = addressMapping.BANKGROUP_BIT)
|
||||
{
|
||||
std::copy(bankGroupBits->begin(), bankGroupBits->end(), std::back_inserter(vBankGroupBits));
|
||||
addMapping(*bankGroupBits, vBankGroupBits, vXor);
|
||||
}
|
||||
|
||||
if (const auto& byteBits = addressMapping.BYTE_BIT)
|
||||
{
|
||||
std::copy(byteBits->begin(), byteBits->end(), std::back_inserter(vByteBits));
|
||||
}
|
||||
|
||||
if (const auto& xorBits = addressMapping.XOR)
|
||||
{
|
||||
for (const auto& xorBit : *xorBits)
|
||||
{
|
||||
vXor.emplace_back(xorBit.FIRST, xorBit.SECOND);
|
||||
}
|
||||
addMapping(*byteBits, vByteBits, vXor);
|
||||
}
|
||||
|
||||
if (const auto& bankBits = addressMapping.BANK_BIT)
|
||||
{
|
||||
std::copy(bankBits->begin(), bankBits->end(), std::back_inserter(vBankBits));
|
||||
addMapping(*bankBits, vBankBits, vXor);
|
||||
}
|
||||
|
||||
if (const auto& rowBits = addressMapping.ROW_BIT)
|
||||
{
|
||||
std::copy(rowBits->begin(), rowBits->end(), std::back_inserter(vRowBits));
|
||||
addMapping(*rowBits, vRowBits, vXor);
|
||||
}
|
||||
|
||||
if (const auto& columnBits = addressMapping.COLUMN_BIT)
|
||||
{
|
||||
std::copy(columnBits->begin(), columnBits->end(), std::back_inserter(vColumnBits));
|
||||
addMapping(*columnBits, vColumnBits, vXor);
|
||||
}
|
||||
|
||||
unsigned channels = std::lround(std::pow(2.0, vChannelBits.size()));
|
||||
@@ -188,12 +203,16 @@ DecodedAddress AddressDecoder::decodeAddress(uint64_t encAddr) const
|
||||
// For each used xor:
|
||||
// Get the first bit and second bit. Apply a bitwise xor operator and save it back to the
|
||||
// first bit.
|
||||
auto tempAddr = encAddr;
|
||||
for (const auto& it : vXor)
|
||||
{
|
||||
uint64_t xoredBit =
|
||||
(((encAddr >> it.first) & UINT64_C(1)) ^ ((encAddr >> it.second) & UINT64_C(1)));
|
||||
encAddr &= ~(UINT64_C(1) << it.first);
|
||||
encAddr |= xoredBit << it.first;
|
||||
uint64_t xoredBit = std::accumulate(it.cbegin(),
|
||||
it.cend(),
|
||||
0,
|
||||
[tempAddr](uint64_t acc, unsigned xorBit)
|
||||
{ return acc ^= (tempAddr >> xorBit) & UINT64_C(1); });
|
||||
encAddr &= ~(UINT64_C(1) << it[0]);
|
||||
encAddr |= xoredBit << it[0];
|
||||
}
|
||||
|
||||
DecodedAddress decAddr;
|
||||
@@ -238,12 +257,16 @@ unsigned AddressDecoder::decodeChannel(uint64_t encAddr) const
|
||||
// For each used xor:
|
||||
// Get the first bit and second bit. Apply a bitwise xor operator and save it back to the
|
||||
// first bit.
|
||||
auto tempAddr = encAddr;
|
||||
for (const auto& it : vXor)
|
||||
{
|
||||
uint64_t xoredBit =
|
||||
(((encAddr >> it.first) & UINT64_C(1)) ^ ((encAddr >> it.second) & UINT64_C(1)));
|
||||
encAddr &= ~(UINT64_C(1) << it.first);
|
||||
encAddr |= xoredBit << it.first;
|
||||
uint64_t xoredBit = std::accumulate(it.cbegin(),
|
||||
it.cend(),
|
||||
0,
|
||||
[tempAddr](uint64_t acc, unsigned xorBit)
|
||||
{ return acc ^= (tempAddr >> xorBit) & UINT64_C(1); });
|
||||
encAddr &= ~(UINT64_C(1) << it[0]);
|
||||
encAddr |= xoredBit << it[0];
|
||||
}
|
||||
|
||||
unsigned channel = 0;
|
||||
@@ -298,10 +321,13 @@ void AddressDecoder::print() const
|
||||
{
|
||||
uint64_t addressBits =
|
||||
(UINT64_C(1) << vChannelBits[static_cast<std::vector<unsigned>::size_type>(it)]);
|
||||
for (auto it2 : vXor)
|
||||
for (auto xorMapping : vXor)
|
||||
{
|
||||
if (it2.first == vChannelBits[static_cast<std::vector<unsigned>::size_type>(it)])
|
||||
addressBits |= (UINT64_C(1) << it2.second);
|
||||
if (xorMapping.at(0) == vChannelBits[static_cast<std::vector<unsigned>::size_type>(it)])
|
||||
{
|
||||
for (auto it = xorMapping.cbegin() + 1; it != xorMapping.cend(); it++)
|
||||
addressBits |= (UINT64_C(1) << *it);
|
||||
}
|
||||
}
|
||||
std::cout << " Ch " << std::setw(2) << it << ": " << std::bitset<64>(addressBits)
|
||||
<< std::endl;
|
||||
@@ -311,10 +337,13 @@ void AddressDecoder::print() const
|
||||
{
|
||||
uint64_t addressBits =
|
||||
(UINT64_C(1) << vRankBits[static_cast<std::vector<unsigned>::size_type>(it)]);
|
||||
for (auto it2 : vXor)
|
||||
for (auto xorMapping : vXor)
|
||||
{
|
||||
if (it2.first == vRankBits[static_cast<std::vector<unsigned>::size_type>(it)])
|
||||
addressBits |= (UINT64_C(1) << it2.second);
|
||||
if (xorMapping.at(0) == vRankBits[static_cast<std::vector<unsigned>::size_type>(it)])
|
||||
{
|
||||
for (auto it = xorMapping.cbegin() + 1; it != xorMapping.cend(); it++)
|
||||
addressBits |= (UINT64_C(1) << *it);
|
||||
}
|
||||
}
|
||||
std::cout << " Ra " << std::setw(2) << it << ": " << std::bitset<64>(addressBits)
|
||||
<< std::endl;
|
||||
@@ -324,10 +353,14 @@ void AddressDecoder::print() const
|
||||
{
|
||||
uint64_t addressBits =
|
||||
(UINT64_C(1) << vBankGroupBits[static_cast<std::vector<unsigned>::size_type>(it)]);
|
||||
for (auto it2 : vXor)
|
||||
for (auto xorMapping : vXor)
|
||||
{
|
||||
if (it2.first == vBankGroupBits[static_cast<std::vector<unsigned>::size_type>(it)])
|
||||
addressBits |= (UINT64_C(1) << it2.second);
|
||||
if (xorMapping.at(0) ==
|
||||
vBankGroupBits[static_cast<std::vector<unsigned>::size_type>(it)])
|
||||
{
|
||||
for (auto it = xorMapping.cbegin() + 1; it != xorMapping.cend(); it++)
|
||||
addressBits |= (UINT64_C(1) << *it);
|
||||
}
|
||||
}
|
||||
std::cout << " Bg " << std::setw(2) << it << ": " << std::bitset<64>(addressBits)
|
||||
<< std::endl;
|
||||
@@ -337,10 +370,13 @@ void AddressDecoder::print() const
|
||||
{
|
||||
uint64_t addressBits =
|
||||
(UINT64_C(1) << vBankBits[static_cast<std::vector<unsigned>::size_type>(it)]);
|
||||
for (auto it2 : vXor)
|
||||
for (auto xorMapping : vXor)
|
||||
{
|
||||
if (it2.first == vBankBits[static_cast<std::vector<unsigned>::size_type>(it)])
|
||||
addressBits |= (UINT64_C(1) << it2.second);
|
||||
if (xorMapping.at(0) == vBankBits[static_cast<std::vector<unsigned>::size_type>(it)])
|
||||
{
|
||||
for (auto it = xorMapping.cbegin() + 1; it != xorMapping.cend(); it++)
|
||||
addressBits |= (UINT64_C(1) << *it);
|
||||
}
|
||||
}
|
||||
std::cout << " Ba " << std::setw(2) << it << ": " << std::bitset<64>(addressBits)
|
||||
<< std::endl;
|
||||
@@ -350,10 +386,13 @@ void AddressDecoder::print() const
|
||||
{
|
||||
uint64_t addressBits =
|
||||
(UINT64_C(1) << vRowBits[static_cast<std::vector<unsigned>::size_type>(it)]);
|
||||
for (auto it2 : vXor)
|
||||
for (auto xorMapping : vXor)
|
||||
{
|
||||
if (it2.first == vRowBits[static_cast<std::vector<unsigned>::size_type>(it)])
|
||||
addressBits |= (UINT64_C(1) << it2.second);
|
||||
if (xorMapping.at(0) == vRowBits[static_cast<std::vector<unsigned>::size_type>(it)])
|
||||
{
|
||||
for (auto it = xorMapping.cbegin() + 1; it != xorMapping.cend(); it++)
|
||||
addressBits |= (UINT64_C(1) << *it);
|
||||
}
|
||||
}
|
||||
std::cout << " Ro " << std::setw(2) << it << ": " << std::bitset<64>(addressBits)
|
||||
<< std::endl;
|
||||
@@ -363,10 +402,13 @@ void AddressDecoder::print() const
|
||||
{
|
||||
uint64_t addressBits =
|
||||
(UINT64_C(1) << vColumnBits[static_cast<std::vector<unsigned>::size_type>(it)]);
|
||||
for (auto it2 : vXor)
|
||||
for (auto xorMapping : vXor)
|
||||
{
|
||||
if (it2.first == vColumnBits[static_cast<std::vector<unsigned>::size_type>(it)])
|
||||
addressBits |= (UINT64_C(1) << it2.second);
|
||||
if (xorMapping.at(0) == vColumnBits[static_cast<std::vector<unsigned>::size_type>(it)])
|
||||
{
|
||||
for (auto it = xorMapping.cbegin() + 1; it != xorMapping.cend(); it++)
|
||||
addressBits |= (UINT64_C(1) << *it);
|
||||
}
|
||||
}
|
||||
std::cout << " Co " << std::setw(2) << it << ": " << std::bitset<64>(addressBits)
|
||||
<< std::endl;
|
||||
@@ -376,10 +418,13 @@ void AddressDecoder::print() const
|
||||
{
|
||||
uint64_t addressBits =
|
||||
(UINT64_C(1) << vByteBits[static_cast<std::vector<unsigned>::size_type>(it)]);
|
||||
for (auto it2 : vXor)
|
||||
for (auto xorMapping : vXor)
|
||||
{
|
||||
if (it2.first == vByteBits[static_cast<std::vector<unsigned>::size_type>(it)])
|
||||
addressBits |= (UINT64_C(1) << it2.second);
|
||||
if (xorMapping.at(0) == vByteBits[static_cast<std::vector<unsigned>::size_type>(it)])
|
||||
{
|
||||
for (auto it = xorMapping.cbegin() + 1; it != xorMapping.cend(); it++)
|
||||
addressBits |= (UINT64_C(1) << *it);
|
||||
}
|
||||
}
|
||||
std::cout << " By " << std::setw(2) << it << ": " << std::bitset<64>(addressBits)
|
||||
<< std::endl;
|
||||
|
||||
@@ -99,7 +99,7 @@ private:
|
||||
|
||||
// This container stores for each used xor gate a pair of address bits, the first bit is
|
||||
// overwritten with the result
|
||||
std::vector<std::pair<unsigned, unsigned>> vXor;
|
||||
std::vector<std::vector<unsigned>> vXor;
|
||||
std::vector<unsigned> vChannelBits;
|
||||
std::vector<unsigned> vRankBits;
|
||||
std::vector<unsigned> vBankGroupBits;
|
||||
|
||||
@@ -62,15 +62,19 @@ protected:
|
||||
static DRAMSys::Config::TrafficGeneratorStateMachine createTraceGeneratorMultipleStates();
|
||||
static DRAMSys::Config::RowHammer createTraceHammer();
|
||||
|
||||
static std::vector<DRAMSys::Config::AddressMapping::BitEntry>
|
||||
addressMapBitVector(std::vector<unsigned> bits)
|
||||
{
|
||||
return {bits.begin(), bits.end()};
|
||||
};
|
||||
|
||||
DRAMSys::Config::AddressMapping addressMapping{
|
||||
{{0, 1}},
|
||||
{{2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}},
|
||||
{{16}},
|
||||
{{13, 14, 15}},
|
||||
{{17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}},
|
||||
{{33}},
|
||||
std::nullopt,
|
||||
std::nullopt,
|
||||
addressMapBitVector({0, 1}),
|
||||
addressMapBitVector({2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}),
|
||||
addressMapBitVector({16}),
|
||||
addressMapBitVector({13, 14, 15}),
|
||||
addressMapBitVector({17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}),
|
||||
addressMapBitVector({33}),
|
||||
std::nullopt};
|
||||
|
||||
DRAMSys::Config::McConfig mcConfig{PagePolicyType::Open,
|
||||
|
||||
@@ -1,14 +1,8 @@
|
||||
{
|
||||
"simulation": {
|
||||
"addressmapping": {
|
||||
"XOR": [
|
||||
{
|
||||
"FIRST": 13,
|
||||
"SECOND": 16
|
||||
}
|
||||
],
|
||||
"BANK_BIT": [
|
||||
13,
|
||||
[13, 16],
|
||||
14,
|
||||
15
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user