From a25a4b78391c4f6ca55195f1c3e18752a7f5ab6f Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Fri, 25 Oct 2024 19:50:11 +0000 Subject: [PATCH] miranda: check request operation instead of using dynamic_cast For my simulation, approximately 15-20% of CPU time is spent resolving one dynamic_cast in miranda. This dynamic cast does not appear to be necessary because mirandaCPU dispatches GeneratorRequests based on the request's operation. This patch replaces the dynamic_cast with an operation check and adds an assertion on the MemoryOpRequest's operation type. The assertion ensures a MemoryOpRequest is either READ or WRITE to avoid potential incorrect static_cast'ing into CustomOpRequests. --- src/sst/elements/miranda/mirandaCPU.cc | 12 ++++++------ src/sst/elements/miranda/mirandaGenerator.h | 5 +++-- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/sst/elements/miranda/mirandaCPU.cc b/src/sst/elements/miranda/mirandaCPU.cc index ecf127b0e6..4df015ddee 100644 --- a/src/sst/elements/miranda/mirandaCPU.cc +++ b/src/sst/elements/miranda/mirandaCPU.cc @@ -463,10 +463,10 @@ bool RequestGenCPU::clockTick(SST::Cycle_t cycle) { break; } - MemoryOpRequest* memOpReq; GeneratorRequest* nxtRq = pendingRequests.at(i); + ReqOperation op = nxtRq->getOperation(); - if(nxtRq->getOperation() == REQ_FENCE) { + if(op == REQ_FENCE) { if(0 == requestsInFlight.size()) { out->verbose(CALL_INFO, 4, 0, "Fence operation completed, no pending requests, will be retired.\n"); @@ -483,7 +483,7 @@ bool RequestGenCPU::clockTick(SST::Cycle_t cycle) { // Fence operations do now allow anything else to complete in this cycle break; - } else if (nxtRq->getOperation() == CUSTOM) { + } else if (op == CUSTOM) { if (requestsPending[CUSTOM] < maxRequestsPending[CUSTOM]) { out->verbose(CALL_INFO, 4, 0, "Will attempt to issue as free slots in the load/store unit.\n"); @@ -501,9 +501,9 @@ bool RequestGenCPU::clockTick(SST::Cycle_t cycle) { delete nxtRq; } } - } else if ( ( memOpReq = dynamic_cast(nxtRq) ) ) { - - if( requestsPending[memOpReq->getOperation()] < maxRequestsPending[memOpReq->getOperation()] ) { + } else if (op == READ || op == WRITE) { + if( requestsPending[op] < maxRequestsPending[op] ) { + auto memOpReq = static_cast(nxtRq); out->verbose(CALL_INFO, 4, 0, "Will attempt to issue as free slots in the load/store unit.\n"); diff --git a/src/sst/elements/miranda/mirandaGenerator.h b/src/sst/elements/miranda/mirandaGenerator.h index d20b0a51c8..98d0f8e8b8 100644 --- a/src/sst/elements/miranda/mirandaGenerator.h +++ b/src/sst/elements/miranda/mirandaGenerator.h @@ -180,12 +180,13 @@ class MemoryOpRequest : public GeneratorRequest { const uint64_t cLength, const ReqOperation cOpType) : GeneratorRequest(), - addr(cAddr), length(cLength), op(cOpType) {} + addr(cAddr), length(cLength), op(cOpType) + { assert (op == READ || op == WRITE); } + ~MemoryOpRequest() {} ReqOperation getOperation() const { return op; } bool isRead() const { return op == READ; } bool isWrite() const { return op == WRITE; } - bool isCustom() const { return op == CUSTOM; } uint64_t getAddress() const { return addr; } uint64_t getLength() const { return length; }