arch,cpu: Add boilerplate support for matrix registers
We add initial support for matrix registers to the CPU models and add stubs in each architecture. There are no implementations of matrix registers added, but this provides the basic support for using them in the future. Jira Issue: https://gem5.atlassian.net/browse/GEM5-1289 Change-Id: I2ca6a21da932a58a801a0d08f0ad0cdca4968d02 Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/64333 Maintainer: Giacomo Travaglini <giacomo.travaglini@arm.com> Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com> Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
committed by
Giacomo Travaglini
parent
dd6595bf56
commit
fed81f3408
@@ -52,6 +52,7 @@ class StaticInstFlags(Enum):
|
||||
"IsFloating", # References FP regs.
|
||||
"IsVector", # References Vector regs.
|
||||
"IsVectorElem", # References Vector reg elems.
|
||||
"IsMatrix", # References Matrix regs.
|
||||
"IsLoad", # Reads from memory (load or prefetch).
|
||||
"IsStore", # Writes to memory.
|
||||
"IsAtomic", # Does atomic RMW to memory.
|
||||
|
||||
@@ -70,6 +70,10 @@ Scoreboard::findIndex(const RegId& reg, Index &scoreboard_index)
|
||||
scoreboard_index = vecPredRegOffset + reg.index();
|
||||
ret = true;
|
||||
break;
|
||||
case MatRegClass:
|
||||
scoreboard_index = matRegOffset + reg.index();
|
||||
ret = true;
|
||||
break;
|
||||
case CCRegClass:
|
||||
scoreboard_index = ccRegOffset + reg.index();
|
||||
ret = true;
|
||||
|
||||
@@ -72,6 +72,7 @@ class Scoreboard : public Named
|
||||
const unsigned ccRegOffset;
|
||||
const unsigned vecRegOffset;
|
||||
const unsigned vecPredRegOffset;
|
||||
const unsigned matRegOffset;
|
||||
|
||||
/** The number of registers in the Scoreboard. These
|
||||
* are just the integer, CC and float registers packed
|
||||
@@ -116,7 +117,9 @@ class Scoreboard : public Named
|
||||
vecRegOffset(ccRegOffset + reg_classes.at(CCRegClass)->numRegs()),
|
||||
vecPredRegOffset(vecRegOffset +
|
||||
reg_classes.at(VecElemClass)->numRegs()),
|
||||
numRegs(vecPredRegOffset + reg_classes.at(VecPredRegClass)->numRegs()),
|
||||
matRegOffset(vecPredRegOffset +
|
||||
reg_classes.at(VecPredRegClass)->numRegs()),
|
||||
numRegs(matRegOffset + reg_classes.at(MatRegClass)->numRegs()),
|
||||
numResults(numRegs, 0),
|
||||
numUnpredictableResults(numRegs, 0),
|
||||
fuIndices(numRegs, invalidFUIndex),
|
||||
|
||||
@@ -168,6 +168,7 @@ class BaseO3CPU(BaseCPU):
|
||||
numPhysVecPredRegs = Param.Unsigned(
|
||||
32, "Number of physical predicate registers"
|
||||
)
|
||||
numPhysMatRegs = Param.Unsigned(2, "Number of physical matrix registers")
|
||||
# most ISAs don't use condition-code regs, so default is 0
|
||||
numPhysCCRegs = Param.Unsigned(0, "Number of physical cc registers")
|
||||
numIQEntries = Param.Unsigned(64, "Number of instruction queue entries")
|
||||
|
||||
@@ -90,6 +90,7 @@ CPU::CPU(const BaseO3CPUParams ¶ms)
|
||||
params.numPhysFloatRegs,
|
||||
params.numPhysVecRegs,
|
||||
params.numPhysVecPredRegs,
|
||||
params.numPhysMatRegs,
|
||||
params.numPhysCCRegs,
|
||||
params.isa[0]->regClasses()),
|
||||
|
||||
@@ -200,6 +201,8 @@ CPU::CPU(const BaseO3CPUParams ¶ms)
|
||||
numThreads * regClasses.at(VecRegClass)->numRegs());
|
||||
assert(params.numPhysVecPredRegs >=
|
||||
numThreads * regClasses.at(VecPredRegClass)->numRegs());
|
||||
assert(params.numPhysMatRegs >=
|
||||
numThreads * regClasses.at(MatRegClass)->numRegs());
|
||||
assert(params.numPhysCCRegs >=
|
||||
numThreads * regClasses.at(CCRegClass)->numRegs());
|
||||
|
||||
|
||||
@@ -108,6 +108,7 @@ InstructionQueue::InstructionQueue(CPU *cpu_ptr, IEW *iew_ptr,
|
||||
reg_classes.at(VecElemClass)->numRegs() /
|
||||
reg_classes.at(VecRegClass)->numRegs()) +
|
||||
params.numPhysVecPredRegs +
|
||||
params.numPhysMatRegs +
|
||||
params.numPhysCCRegs;
|
||||
|
||||
//Create an entry for each physical register within the
|
||||
|
||||
@@ -53,6 +53,7 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
|
||||
unsigned _numPhysicalFloatRegs,
|
||||
unsigned _numPhysicalVecRegs,
|
||||
unsigned _numPhysicalVecPredRegs,
|
||||
unsigned _numPhysicalMatRegs,
|
||||
unsigned _numPhysicalCCRegs,
|
||||
const BaseISA::RegClasses ®_classes)
|
||||
: intRegFile(*reg_classes.at(IntRegClass), _numPhysicalIntRegs),
|
||||
@@ -63,6 +64,7 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
|
||||
reg_classes.at(VecRegClass)->numRegs())),
|
||||
vecPredRegFile(*reg_classes.at(VecPredRegClass),
|
||||
_numPhysicalVecPredRegs),
|
||||
matRegFile(*reg_classes.at(MatRegClass), _numPhysicalMatRegs),
|
||||
ccRegFile(*reg_classes.at(CCRegClass), _numPhysicalCCRegs),
|
||||
numPhysicalIntRegs(_numPhysicalIntRegs),
|
||||
numPhysicalFloatRegs(_numPhysicalFloatRegs),
|
||||
@@ -71,12 +73,14 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
|
||||
reg_classes.at(VecElemClass)->numRegs() /
|
||||
reg_classes.at(VecRegClass)->numRegs())),
|
||||
numPhysicalVecPredRegs(_numPhysicalVecPredRegs),
|
||||
numPhysicalMatRegs(_numPhysicalMatRegs),
|
||||
numPhysicalCCRegs(_numPhysicalCCRegs),
|
||||
totalNumRegs(_numPhysicalIntRegs
|
||||
+ _numPhysicalFloatRegs
|
||||
+ _numPhysicalVecRegs
|
||||
+ numPhysicalVecElemRegs
|
||||
+ _numPhysicalVecPredRegs
|
||||
+ _numPhysicalMatRegs
|
||||
+ _numPhysicalCCRegs)
|
||||
{
|
||||
RegIndex phys_reg;
|
||||
@@ -115,6 +119,13 @@ PhysRegFile::PhysRegFile(unsigned _numPhysicalIntRegs,
|
||||
flat_reg_idx++);
|
||||
}
|
||||
|
||||
// The next batch of the registers are the matrix physical
|
||||
// registers; put them onto the matrix free list.
|
||||
for (phys_reg = 0; phys_reg < numPhysicalMatRegs; phys_reg++) {
|
||||
matRegIds.emplace_back(*reg_classes.at(MatRegClass), phys_reg,
|
||||
flat_reg_idx++);
|
||||
}
|
||||
|
||||
// The rest of the registers are the condition-code physical
|
||||
// registers; put them onto the condition-code free list.
|
||||
for (phys_reg = 0; phys_reg < numPhysicalCCRegs; phys_reg++) {
|
||||
@@ -167,6 +178,13 @@ PhysRegFile::initFreeList(UnifiedFreeList *freeList)
|
||||
}
|
||||
freeList->addRegs(vecPredRegIds.begin(), vecPredRegIds.end());
|
||||
|
||||
/* The next batch of the registers are the matrix physical
|
||||
* registers; put them onto the matrix free list. */
|
||||
for (reg_idx = 0; reg_idx < numPhysicalMatRegs; reg_idx++) {
|
||||
assert(matRegIds[reg_idx].index() == reg_idx);
|
||||
}
|
||||
freeList->addRegs(matRegIds.begin(), matRegIds.end());
|
||||
|
||||
// The rest of the registers are the condition-code physical
|
||||
// registers; put them onto the condition-code free list.
|
||||
for (reg_idx = 0; reg_idx < numPhysicalCCRegs; reg_idx++) {
|
||||
|
||||
@@ -91,6 +91,10 @@ class PhysRegFile
|
||||
RegFile vecPredRegFile;
|
||||
std::vector<PhysRegId> vecPredRegIds;
|
||||
|
||||
/** Matrix register file. */
|
||||
RegFile matRegFile;
|
||||
std::vector<PhysRegId> matRegIds;
|
||||
|
||||
/** Condition-code register file. */
|
||||
RegFile ccRegFile;
|
||||
std::vector<PhysRegId> ccRegIds;
|
||||
@@ -123,6 +127,11 @@ class PhysRegFile
|
||||
*/
|
||||
unsigned numPhysicalVecPredRegs;
|
||||
|
||||
/**
|
||||
* Number of physical matrix registers
|
||||
*/
|
||||
unsigned numPhysicalMatRegs;
|
||||
|
||||
/**
|
||||
* Number of physical CC registers
|
||||
*/
|
||||
@@ -140,6 +149,7 @@ class PhysRegFile
|
||||
unsigned _numPhysicalFloatRegs,
|
||||
unsigned _numPhysicalVecRegs,
|
||||
unsigned _numPhysicalVecPredRegs,
|
||||
unsigned _numPhysicalMatRegs,
|
||||
unsigned _numPhysicalCCRegs,
|
||||
const BaseISA::RegClasses &classes);
|
||||
|
||||
@@ -218,6 +228,11 @@ class PhysRegFile
|
||||
DPRINTF(IEW, "RegFile: Access to predicate register %i, has "
|
||||
"data %s\n", idx, vecPredRegFile.regClass.valString(val));
|
||||
break;
|
||||
case MatRegClass:
|
||||
matRegFile.get(idx, val);
|
||||
DPRINTF(IEW, "RegFile: Access to matrix register %i, has "
|
||||
"data %s\n", idx, matRegFile.regClass.valString(val));
|
||||
break;
|
||||
case CCRegClass:
|
||||
*(RegVal *)val = getReg(phys_reg);
|
||||
break;
|
||||
@@ -237,6 +252,8 @@ class PhysRegFile
|
||||
return vectorRegFile.ptr(idx);
|
||||
case VecPredRegClass:
|
||||
return vecPredRegFile.ptr(idx);
|
||||
case MatRegClass:
|
||||
return matRegFile.ptr(idx);
|
||||
default:
|
||||
panic("Unrecognized register class type %d.", type);
|
||||
}
|
||||
@@ -302,6 +319,11 @@ class PhysRegFile
|
||||
idx, vecPredRegFile.regClass.valString(val));
|
||||
vecPredRegFile.set(idx, val);
|
||||
break;
|
||||
case MatRegClass:
|
||||
DPRINTF(IEW, "RegFile: Setting matrix register %i to %s\n",
|
||||
idx, matRegFile.regClass.valString(val));
|
||||
matRegFile.set(idx, val);
|
||||
break;
|
||||
case CCRegClass:
|
||||
setReg(phys_reg, *(RegVal *)val);
|
||||
break;
|
||||
|
||||
@@ -134,6 +134,8 @@ Rename::RenameStats::RenameStats(statistics::Group *parent)
|
||||
"Number of vector rename lookups"),
|
||||
ADD_STAT(vecPredLookups, statistics::units::Count::get(),
|
||||
"Number of vector predicate rename lookups"),
|
||||
ADD_STAT(matLookups, statistics::units::Count::get(),
|
||||
"Number of matrix rename lookups"),
|
||||
ADD_STAT(committedMaps, statistics::units::Count::get(),
|
||||
"Number of HB maps that are committed"),
|
||||
ADD_STAT(undoneMaps, statistics::units::Count::get(),
|
||||
@@ -167,6 +169,7 @@ Rename::RenameStats::RenameStats(statistics::Group *parent)
|
||||
fpLookups.prereq(fpLookups);
|
||||
vecLookups.prereq(vecLookups);
|
||||
vecPredLookups.prereq(vecPredLookups);
|
||||
matLookups.prereq(matLookups);
|
||||
|
||||
committedMaps.prereq(committedMaps);
|
||||
undoneMaps.prereq(undoneMaps);
|
||||
@@ -1034,6 +1037,9 @@ Rename::renameSrcRegs(const DynInstPtr &inst, ThreadID tid)
|
||||
case VecPredRegClass:
|
||||
stats.vecPredLookups++;
|
||||
break;
|
||||
case MatRegClass:
|
||||
stats.matLookups++;
|
||||
break;
|
||||
case CCRegClass:
|
||||
case MiscRegClass:
|
||||
break;
|
||||
@@ -1248,7 +1254,7 @@ Rename::readFreeEntries(ThreadID tid)
|
||||
}
|
||||
|
||||
DPRINTF(Rename, "[tid:%i] Free IQ: %i, Free ROB: %i, "
|
||||
"Free LQ: %i, Free SQ: %i, FreeRM %i(%i %i %i %i %i %i)\n",
|
||||
"Free LQ: %i, Free SQ: %i, FreeRM %i(%i %i %i %i %i %i %i)\n",
|
||||
tid,
|
||||
freeEntries[tid].iqEntries,
|
||||
freeEntries[tid].robEntries,
|
||||
@@ -1260,6 +1266,7 @@ Rename::readFreeEntries(ThreadID tid)
|
||||
renameMap[tid]->numFreeEntries(VecRegClass),
|
||||
renameMap[tid]->numFreeEntries(VecElemClass),
|
||||
renameMap[tid]->numFreeEntries(VecPredRegClass),
|
||||
renameMap[tid]->numFreeEntries(MatRegClass),
|
||||
renameMap[tid]->numFreeEntries(CCRegClass));
|
||||
|
||||
DPRINTF(Rename, "[tid:%i] %i instructions not yet in ROB\n",
|
||||
|
||||
@@ -521,6 +521,7 @@ class Rename
|
||||
statistics::Scalar fpLookups;
|
||||
statistics::Scalar vecLookups;
|
||||
statistics::Scalar vecPredLookups;
|
||||
statistics::Scalar matLookups;
|
||||
/** Stat for total number of committed renaming mappings. */
|
||||
statistics::Scalar committedMaps;
|
||||
/** Stat for total number of mappings that were undone due to a
|
||||
|
||||
@@ -64,6 +64,7 @@ enum RegClassType
|
||||
/** Vector Register Native Elem lane. */
|
||||
VecElemClass,
|
||||
VecPredRegClass,
|
||||
MatRegClass, ///< Matrix Register
|
||||
CCRegClass, ///< Condition-code register
|
||||
MiscRegClass, ///< Control (misc) register
|
||||
InvalidRegClass = -1
|
||||
@@ -75,6 +76,7 @@ inline constexpr char FloatRegClassName[] = "floating_point";
|
||||
inline constexpr char VecRegClassName[] = "vector";
|
||||
inline constexpr char VecElemClassName[] = "vector_element";
|
||||
inline constexpr char VecPredRegClassName[] = "vector_predicate";
|
||||
inline constexpr char MatRegClassName[] = "matrix";
|
||||
inline constexpr char CCRegClassName[] = "condition_code";
|
||||
inline constexpr char MiscRegClassName[] = "miscellaneous";
|
||||
|
||||
|
||||
@@ -418,6 +418,12 @@ BaseSimpleCPU::postExecute()
|
||||
t_info.execContextStats.numVecInsts++;
|
||||
}
|
||||
|
||||
//Matrix alu accesses
|
||||
if (curStaticInst->isMatrix()){
|
||||
t_info.execContextStats.numMatAluAccesses++;
|
||||
t_info.execContextStats.numMatInsts++;
|
||||
}
|
||||
|
||||
//number of function calls/returns to get window accesses
|
||||
if (curStaticInst->isCall() || curStaticInst->isReturn()){
|
||||
t_info.execContextStats.numCallsReturns++;
|
||||
|
||||
@@ -96,6 +96,8 @@ class SimpleExecContext : public ExecContext
|
||||
"Number of float alu accesses"),
|
||||
ADD_STAT(numVecAluAccesses, statistics::units::Count::get(),
|
||||
"Number of vector alu accesses"),
|
||||
ADD_STAT(numMatAluAccesses, statistics::units::Count::get(),
|
||||
"Number of matrix alu accesses"),
|
||||
ADD_STAT(numCallsReturns, statistics::units::Count::get(),
|
||||
"Number of times a function call or return occured"),
|
||||
ADD_STAT(numCondCtrlInsts, statistics::units::Count::get(),
|
||||
@@ -106,6 +108,8 @@ class SimpleExecContext : public ExecContext
|
||||
"Number of float instructions"),
|
||||
ADD_STAT(numVecInsts, statistics::units::Count::get(),
|
||||
"Number of vector instructions"),
|
||||
ADD_STAT(numMatInsts, statistics::units::Count::get(),
|
||||
"Number of matrix instructions"),
|
||||
ADD_STAT(numIntRegReads, statistics::units::Count::get(),
|
||||
"Number of times the integer registers were read"),
|
||||
ADD_STAT(numIntRegWrites, statistics::units::Count::get(),
|
||||
@@ -162,6 +166,7 @@ class SimpleExecContext : public ExecContext
|
||||
&numVecRegReads,
|
||||
&numVecRegReads,
|
||||
&numVecPredRegReads,
|
||||
&numMatRegReads,
|
||||
&numCCRegReads
|
||||
},
|
||||
numRegWrites{
|
||||
@@ -170,6 +175,7 @@ class SimpleExecContext : public ExecContext
|
||||
&numVecRegWrites,
|
||||
&numVecRegWrites,
|
||||
&numVecPredRegWrites,
|
||||
&numMatRegWrites,
|
||||
&numCCRegWrites
|
||||
}
|
||||
{
|
||||
@@ -220,6 +226,9 @@ class SimpleExecContext : public ExecContext
|
||||
// Number of vector alu accesses
|
||||
statistics::Scalar numVecAluAccesses;
|
||||
|
||||
// Number of matrix alu accesses
|
||||
statistics::Scalar numMatAluAccesses;
|
||||
|
||||
// Number of function calls/returns
|
||||
statistics::Scalar numCallsReturns;
|
||||
|
||||
@@ -235,6 +244,9 @@ class SimpleExecContext : public ExecContext
|
||||
// Number of vector instructions
|
||||
statistics::Scalar numVecInsts;
|
||||
|
||||
// Number of matrix instructions
|
||||
statistics::Scalar numMatInsts;
|
||||
|
||||
// Number of integer register file accesses
|
||||
statistics::Scalar numIntRegReads;
|
||||
statistics::Scalar numIntRegWrites;
|
||||
@@ -251,6 +263,10 @@ class SimpleExecContext : public ExecContext
|
||||
mutable statistics::Scalar numVecPredRegReads;
|
||||
statistics::Scalar numVecPredRegWrites;
|
||||
|
||||
// Number of matrix register file accesses
|
||||
mutable statistics::Scalar numMatRegReads;
|
||||
statistics::Scalar numMatRegWrites;
|
||||
|
||||
// Number of condition code register file accesses
|
||||
statistics::Scalar numCCRegReads;
|
||||
statistics::Scalar numCCRegWrites;
|
||||
|
||||
@@ -75,6 +75,7 @@ SimpleThread::SimpleThread(BaseCPU *_cpu, int _thread_num, System *_sys,
|
||||
{*_isa->regClasses().at(VecRegClass)},
|
||||
{*_isa->regClasses().at(VecElemClass)},
|
||||
{*_isa->regClasses().at(VecPredRegClass)},
|
||||
{*_isa->regClasses().at(MatRegClass)},
|
||||
{*_isa->regClasses().at(CCRegClass)}
|
||||
}},
|
||||
isa(_isa),
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
#include "debug/CCRegs.hh"
|
||||
#include "debug/FloatRegs.hh"
|
||||
#include "debug/IntRegs.hh"
|
||||
#include "debug/MatRegs.hh"
|
||||
#include "debug/VecPredRegs.hh"
|
||||
#include "debug/VecRegs.hh"
|
||||
#include "mem/htm.hh"
|
||||
|
||||
@@ -155,6 +155,7 @@ class StaticInst : public RefCounted, public StaticInstFlags
|
||||
bool isInteger() const { return flags[IsInteger]; }
|
||||
bool isFloating() const { return flags[IsFloating]; }
|
||||
bool isVector() const { return flags[IsVector]; }
|
||||
bool isMatrix() const { return flags[IsMatrix]; }
|
||||
|
||||
bool isControl() const { return flags[IsControl]; }
|
||||
bool isCall() const { return flags[IsCall]; }
|
||||
|
||||
@@ -109,6 +109,20 @@ ThreadContext::compare(ThreadContext *one, ThreadContext *two)
|
||||
}
|
||||
}
|
||||
|
||||
// Then loop through the matrix registers.
|
||||
const auto *mat_class = regClasses.at(MatRegClass);
|
||||
std::vector<uint8_t> mat1(mat_class->regBytes());
|
||||
std::vector<uint8_t> mat2(mat_class->regBytes());
|
||||
for (auto &id: *regClasses.at(MatRegClass)) {
|
||||
one->getReg(id, mat1.data());
|
||||
two->getReg(id, mat2.data());
|
||||
if (mat1 != mat2) {
|
||||
panic("Mat reg idx %d doesn't match, one: %#x, two: %#x",
|
||||
id.index(), mat_class->valString(mat1.data()),
|
||||
mat_class->valString(mat2.data()));
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < regClasses.at(MiscRegClass)->numRegs(); ++i) {
|
||||
RegVal t1 = one->readMiscRegNoEffect(i);
|
||||
RegVal t2 = two->readMiscRegNoEffect(i);
|
||||
|
||||
Reference in New Issue
Block a user