Add support for more than two XOR bits

This commit is contained in:
2023-12-12 13:17:11 +01:00
parent a89f4a3065
commit 1ba63bd1f7
6 changed files with 118 additions and 82 deletions

View File

@@ -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);
}
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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;

View File

@@ -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,

View File

@@ -1,14 +1,8 @@
{
"simulation": {
"addressmapping": {
"XOR": [
{
"FIRST": 13,
"SECOND": 16
}
],
"BANK_BIT": [
13,
[13, 16],
14,
15
],