Alexandru Duțu has uploaded this change for review. ( https://gem5-review.googlesource.com/c/public/gem5/+/39115 )

Change subject: arch-gcn3: Implementation of s_sleep
......................................................................

arch-gcn3: Implementation of s_sleep

This changeset implements the s_sleep instruction in a similar
way to s_waitcnt.

Change-Id: I4811c318ac2c76c485e2bfd9d93baa1205ecf183
---
M src/arch/gcn3/insts/instructions.cc
M src/gpu-compute/GPUStaticInstFlags.py
M src/gpu-compute/gpu_dyn_inst.cc
M src/gpu-compute/gpu_dyn_inst.hh
M src/gpu-compute/gpu_static_inst.hh
M src/gpu-compute/schedule_stage.cc
M src/gpu-compute/scoreboard_check_stage.cc
M src/gpu-compute/scoreboard_check_stage.hh
M src/gpu-compute/wavefront.cc
M src/gpu-compute/wavefront.hh
10 files changed, 81 insertions(+), 4 deletions(-)



diff --git a/src/arch/gcn3/insts/instructions.cc b/src/arch/gcn3/insts/instructions.cc
index e8951a9..ff939fc 100644
--- a/src/arch/gcn3/insts/instructions.cc
+++ b/src/arch/gcn3/insts/instructions.cc
@@ -4189,6 +4189,9 @@
     Inst_SOPP__S_SLEEP::Inst_SOPP__S_SLEEP(InFmt_SOPP *iFmt)
         : Inst_SOPP(iFmt, "s_sleep")
     {
+        setFlag(ALU);
+        setFlag(Sleep);
+        setFlag(Internal);
     } // Inst_SOPP__S_SLEEP

     Inst_SOPP__S_SLEEP::~Inst_SOPP__S_SLEEP()
@@ -4199,8 +4202,11 @@
     void
     Inst_SOPP__S_SLEEP::execute(GPUDynInstPtr gpuDynInst)
     {
-        panicUnimplemented();
-    }
+        ScalarRegI32 simm16 = (ScalarRegI32)instData.SIMM16;
+        gpuDynInst->wavefront()->setStatus(Wavefront::S_STALLED_SLEEP);
+        gpuDynInst->wavefront()->setSleepTime(64 * simm16);
+    } // execute
+    // --- Inst_SOPP__S_SETPRIO class methods ---

     Inst_SOPP__S_SETPRIO::Inst_SOPP__S_SETPRIO(InFmt_SOPP *iFmt)
         : Inst_SOPP(iFmt, "s_setprio")
diff --git a/src/gpu-compute/GPUStaticInstFlags.py b/src/gpu-compute/GPUStaticInstFlags.py
index ad4c6c3..1dc143c 100644
--- a/src/gpu-compute/GPUStaticInstFlags.py
+++ b/src/gpu-compute/GPUStaticInstFlags.py
@@ -48,6 +48,7 @@
         'UnconditionalJump', #
         'SpecialOp',         # Special op
         'Waitcnt',           # Is a waitcnt instruction
+        'Sleep',             # Is a sleep instruction

         # Memory ops
         'MemBarrier',        # Barrier instruction
diff --git a/src/gpu-compute/gpu_dyn_inst.cc b/src/gpu-compute/gpu_dyn_inst.cc
index 38e4ecf..64ece57 100644
--- a/src/gpu-compute/gpu_dyn_inst.cc
+++ b/src/gpu-compute/gpu_dyn_inst.cc
@@ -399,6 +399,12 @@
 }

 bool
+GPUDynInst::isSleep() const
+{
+    return _staticInst->isSleep();
+}
+
+bool
 GPUDynInst::isBarrier() const
 {
     return _staticInst->isBarrier();
diff --git a/src/gpu-compute/gpu_dyn_inst.hh b/src/gpu-compute/gpu_dyn_inst.hh
index cdb130e..f2e454f 100644
--- a/src/gpu-compute/gpu_dyn_inst.hh
+++ b/src/gpu-compute/gpu_dyn_inst.hh
@@ -180,6 +180,7 @@
     bool isUnconditionalJump() const;
     bool isSpecialOp() const;
     bool isWaitcnt() const;
+    bool isSleep() const;

     bool isBarrier() const;
     bool isMemSync() const;
diff --git a/src/gpu-compute/gpu_static_inst.hh b/src/gpu-compute/gpu_static_inst.hh
index 88fd9f9..f973f2f 100644
--- a/src/gpu-compute/gpu_static_inst.hh
+++ b/src/gpu-compute/gpu_static_inst.hh
@@ -119,6 +119,7 @@

     bool isSpecialOp() const { return _flags[SpecialOp]; }
     bool isWaitcnt() const { return _flags[Waitcnt]; }
+    bool isSleep() const { return _flags[Sleep]; }

     bool isBarrier() const { return _flags[MemBarrier]; }
     bool isMemSync() const { return _flags[MemSync]; }
diff --git a/src/gpu-compute/schedule_stage.cc b/src/gpu-compute/schedule_stage.cc
index 54e9313..b005a89 100644
--- a/src/gpu-compute/schedule_stage.cc
+++ b/src/gpu-compute/schedule_stage.cc
@@ -317,6 +317,9 @@
         if (wf->isOldestInstWaitcnt()) {
             wf->setStatus(Wavefront::S_WAITCNT);
         }
+        if (w->isOldestInstSleep()) {
+            w->setStatus(Wavefront::S_STALLED_SLEEP);
+        }
         if (!gpu_dyn_inst->isScalar()) {
             computeUnit.vrf[wf->simdId]
                 ->scheduleReadOperands(wf, gpu_dyn_inst);
diff --git a/src/gpu-compute/scoreboard_check_stage.cc b/src/gpu-compute/scoreboard_check_stage.cc
index dfda0ad..5500589 100644
--- a/src/gpu-compute/scoreboard_check_stage.cc
+++ b/src/gpu-compute/scoreboard_check_stage.cc
@@ -92,6 +92,15 @@
         }
     }

+    // sleep instruction has been dispatched or executed: next
+    // instruction should be blocked until the sleep period expires.
+    if (w->getStatus() == Wavefront::S_STALLED_SLEEP) {
+        if (!w->sleepDone()) {
+            *rdyStatus = NRDY_SLEEP;
+            return false;
+        }
+    }
+
// Is the wave waiting at a barrier. Check this condition BEFORE checking // for instruction buffer occupancy to avoid a deadlock when the barrier is
     // the last instruction in the instruction buffer.
@@ -143,7 +152,8 @@
     // through this logic and always return not ready.
if (!(ii->isBarrier() || ii->isNop() || ii->isReturn() || ii->isBranch() ||
          ii->isALU() || ii->isLoad() || ii->isStore() || ii->isAtomic() ||
-         ii->isEndOfKernel() || ii->isMemSync() || ii->isFlat())) {
+         ii->isEndOfKernel() || ii->isMemSync() || ii->isFlat() ||
+         ii->isSleep())) {
panic("next instruction: %s is of unknown type\n", ii->disassemble());
     }

diff --git a/src/gpu-compute/scoreboard_check_stage.hh b/src/gpu-compute/scoreboard_check_stage.hh
index c45ea75..714c761 100644
--- a/src/gpu-compute/scoreboard_check_stage.hh
+++ b/src/gpu-compute/scoreboard_check_stage.hh
@@ -64,6 +64,7 @@
         NRDY_WF_STOP,
         NRDY_IB_EMPTY,
         NRDY_WAIT_CNT,
+        NRDY_SLEEP,
         NRDY_BARRIER_WAIT,
         NRDY_VGPR_NRDY,
         NRDY_SGPR_NRDY,
diff --git a/src/gpu-compute/wavefront.cc b/src/gpu-compute/wavefront.cc
index b7ff95a..00c4fd9 100644
--- a/src/gpu-compute/wavefront.cc
+++ b/src/gpu-compute/wavefront.cc
@@ -49,7 +49,7 @@
     maxIbSize(p.max_ib_size), _gpuISA(*this),
     vmWaitCnt(-1), expWaitCnt(-1), lgkmWaitCnt(-1),
     vmemInstsIssued(0), expInstsIssued(0), lgkmInstsIssued(0),
-    barId(WFBarrier::InvalidID)
+    sleepCnt(0), barId(WFBarrier::InvalidID)
 {
     lastTrace = 0;
     execUnitId = -1;
@@ -653,6 +653,20 @@
 }

 bool
+Wavefront::isOldestInstSleep()
+{
+    if (instructionBuffer.empty())
+        return false;
+
+    GPUDynInstPtr ii = instructionBuffer.front();
+
+    if (ii->isSleep()) {
+        return true;
+    }
+    return false;
+}
+
+bool
 Wavefront::isOldestInstWaitcnt()
 {
     if (instructionBuffer.empty())
@@ -1282,6 +1296,32 @@
     return true;
 }

+bool
+Wavefront::sleepDone()
+{
+    assert(status == S_STALLED_SLEEP);
+
+ // if the sleep count has not been set, then the sleep instruction has not + // been executed yet, so we will return true without setting the wavefront
+    // status
+    if (sleepCnt == 0)
+        return false;
+
+    sleepCnt--;
+    if (sleepCnt != 0)
+        return false;
+
+    status = S_RUNNING;
+    return true;
+}
+
+void
+Wavefront::setSleepTime(int sleep_time)
+{
+    assert(sleepCnt == 0);
+    sleepCnt = sleep_time;
+}
+
 void
Wavefront::setWaitCnts(int vm_wait_cnt, int exp_wait_cnt, int lgkm_wait_cnt)
 {
diff --git a/src/gpu-compute/wavefront.hh b/src/gpu-compute/wavefront.hh
index 80fc324..414240c 100644
--- a/src/gpu-compute/wavefront.hh
+++ b/src/gpu-compute/wavefront.hh
@@ -66,6 +66,9 @@
         S_RUNNING,
         // wavefront is stalled
         S_STALLED,
+
+        S_STALLED_SLEEP,
+
         /**
          * wavefront has unsatisfied wait counts
          *
@@ -132,6 +135,7 @@
     bool isGmInstruction(GPUDynInstPtr ii);
     bool isLmInstruction(GPUDynInstPtr ii);
     bool isOldestInstWaitcnt();
+    bool isOldestInstSleep();
     bool isOldestInstGMem();
     bool isOldestInstLMem();
     bool isOldestInstPrivMem();
@@ -314,6 +318,9 @@
     /** Freeing VRF space */
     void freeRegisterFile();

+    bool sleepDone();
+    void setSleepTime(int sleep_time);
+
     TheGpuISA::GPUISA&
     gpuISA()
     {
@@ -353,6 +360,7 @@
     int vmemInstsIssued;
     int expInstsIssued;
     int lgkmInstsIssued;
+    int sleepCnt;
     status_e status;
     Addr _pc;
     VectorMask _execMask;

--
To view, visit https://gem5-review.googlesource.com/c/public/gem5/+/39115
To unsubscribe, or for help writing mail filters, visit https://gem5-review.googlesource.com/settings

Gerrit-Project: public/gem5
Gerrit-Branch: develop
Gerrit-Change-Id: I4811c318ac2c76c485e2bfd9d93baa1205ecf183
Gerrit-Change-Number: 39115
Gerrit-PatchSet: 1
Gerrit-Owner: Alexandru Duțu <[email protected]>
Gerrit-MessageType: newchange
_______________________________________________
gem5-dev mailing list -- [email protected]
To unsubscribe send an email to [email protected]
%(web_page_url)slistinfo%(cgiext)s/%(_internal_name)s

Reply via email to