2 * Copyright (c) 2014-2015 Advanced Micro Devices, Inc.
5 * For use for simulation and test purposes only
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright notice,
14 * this list of conditions and the following disclaimer in the documentation
15 * and/or other materials provided with the distribution.
17 * 3. Neither the name of the copyright holder nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
22 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
25 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
33 * Author: Sooraj Puthoor
36 #include "gpu-compute/scoreboard_check_stage.hh"
38 #include "gpu-compute/compute_unit.hh"
39 #include "gpu-compute/gpu_static_inst.hh"
40 #include "gpu-compute/shader.hh"
41 #include "gpu-compute/wavefront.hh"
42 #include "params/ComputeUnit.hh"
44 ScoreboardCheckStage::ScoreboardCheckStage(const ComputeUnitParams
*p
)
45 : numSIMDs(p
->num_SIMDs
),
46 numMemUnits(p
->num_global_mem_pipes
+ p
->num_shared_mem_pipes
),
47 numShrMemPipes(p
->num_shared_mem_pipes
),
48 vectorAluInstAvail(nullptr),
50 lastShrMemSimd(-1), glbMemInstAvail(nullptr),
51 shrMemInstAvail(nullptr)
55 ScoreboardCheckStage::~ScoreboardCheckStage()
58 waveStatusList
.clear();
59 shrMemInstAvail
= nullptr;
60 glbMemInstAvail
= nullptr;
64 ScoreboardCheckStage::init(ComputeUnit
*cu
)
67 _name
= computeUnit
->name() + ".ScoreboardCheckStage";
69 for (int unitId
= 0; unitId
< numSIMDs
+ numMemUnits
; ++unitId
) {
70 readyList
.push_back(&computeUnit
->readyList
[unitId
]);
73 for (int unitId
= 0; unitId
< numSIMDs
; ++unitId
) {
74 waveStatusList
.push_back(&computeUnit
->waveStatusList
[unitId
]);
77 vectorAluInstAvail
= &computeUnit
->vectorAluInstAvail
;
78 glbMemInstAvail
= &computeUnit
->glbMemInstAvail
;
79 shrMemInstAvail
= &computeUnit
->shrMemInstAvail
;
83 ScoreboardCheckStage::initStatistics()
90 for (int unitId
= 0; unitId
< numSIMDs
; ++unitId
)
91 vectorAluInstAvail
->at(unitId
) = false;
95 ScoreboardCheckStage::collectStatistics(Wavefront
*curWave
, int unitId
)
97 if (curWave
->instructionBuffer
.empty())
100 // track which vector SIMD unit has at least one WV with a vector
101 // ALU as the oldest instruction in its Instruction buffer
102 vectorAluInstAvail
->at(unitId
) = vectorAluInstAvail
->at(unitId
) ||
103 curWave
->isOldestInstALU();
105 // track how many vector SIMD units have at least one WV with a
106 // vector Global memory instruction as the oldest instruction
107 // in its Instruction buffer
108 if ((curWave
->isOldestInstGMem() || curWave
->isOldestInstPrivMem() ||
109 curWave
->isOldestInstFlatMem()) && lastGlbMemSimd
!= unitId
&&
110 *glbMemInstAvail
<= 1) {
111 (*glbMemInstAvail
)++;
112 lastGlbMemSimd
= unitId
;
115 // track how many vector SIMD units have at least one WV with a
116 // vector shared memory (LDS) instruction as the oldest instruction
117 // in its Instruction buffer
118 // TODO: parametrize the limit of the LDS units
119 if (curWave
->isOldestInstLMem() && (*shrMemInstAvail
<= numShrMemPipes
) &&
120 lastShrMemSimd
!= unitId
) {
121 (*shrMemInstAvail
)++;
122 lastShrMemSimd
= unitId
;
127 ScoreboardCheckStage::exec()
131 // reset the ready list for all execution units; it will be
132 // constructed every cycle since resource availability may change
133 for (int unitId
= 0; unitId
< numSIMDs
+ numMemUnits
; ++unitId
) {
134 readyList
[unitId
]->clear();
137 // iterate over the Wavefronts of all SIMD units
138 for (int unitId
= 0; unitId
< numSIMDs
; ++unitId
) {
139 for (int wvId
= 0; wvId
< computeUnit
->shader
->n_wf
; ++wvId
) {
140 // reset the ready status of each wavefront
141 waveStatusList
[unitId
]->at(wvId
).second
= BLOCKED
;
142 Wavefront
*curWave
= waveStatusList
[unitId
]->at(wvId
).first
;
143 collectStatistics(curWave
, unitId
);
145 if (curWave
->ready(Wavefront::I_ALU
)) {
146 readyList
[unitId
]->push_back(curWave
);
147 waveStatusList
[unitId
]->at(wvId
).second
= READY
;
148 } else if (curWave
->ready(Wavefront::I_GLOBAL
)) {
149 if (computeUnit
->cedeSIMD(unitId
, wvId
)) {
153 readyList
[computeUnit
->GlbMemUnitId()]->push_back(curWave
);
154 waveStatusList
[unitId
]->at(wvId
).second
= READY
;
155 } else if (curWave
->ready(Wavefront::I_SHARED
)) {
156 readyList
[computeUnit
->ShrMemUnitId()]->push_back(curWave
);
157 waveStatusList
[unitId
]->at(wvId
).second
= READY
;
158 } else if (curWave
->ready(Wavefront::I_FLAT
)) {
159 readyList
[computeUnit
->GlbMemUnitId()]->push_back(curWave
);
160 waveStatusList
[unitId
]->at(wvId
).second
= READY
;
161 } else if (curWave
->ready(Wavefront::I_PRIVATE
)) {
162 readyList
[computeUnit
->GlbMemUnitId()]->push_back(curWave
);
163 waveStatusList
[unitId
]->at(wvId
).second
= READY
;
170 ScoreboardCheckStage::regStats()