scoreboard_check_stage.cc revision 11394:2bc2120ad76b
1/*
2 * Copyright (c) 2014-2015 Advanced Micro Devices, Inc.
3 * All rights reserved.
4 *
5 * For use for simulation and test purposes only
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions are met:
9 *
10 * 1. Redistributions of source code must retain the above copyright notice,
11 * this list of conditions and the following disclaimer.
12 *
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.
16 *
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.
20 *
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.
32 *
33 * Author: Sooraj Puthoor
34 */
35
36#include "gpu-compute/scoreboard_check_stage.hh"
37
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"
43
44ScoreboardCheckStage::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),
49      lastGlbMemSimd(-1),
50      lastShrMemSimd(-1), glbMemInstAvail(nullptr),
51      shrMemInstAvail(nullptr)
52{
53}
54
55ScoreboardCheckStage::~ScoreboardCheckStage()
56{
57    readyList.clear();
58    waveStatusList.clear();
59    shrMemInstAvail = nullptr;
60    glbMemInstAvail = nullptr;
61}
62
63void
64ScoreboardCheckStage::init(ComputeUnit *cu)
65{
66    computeUnit = cu;
67    _name = computeUnit->name() + ".ScoreboardCheckStage";
68
69    for (int unitId = 0; unitId < numSIMDs + numMemUnits; ++unitId) {
70        readyList.push_back(&computeUnit->readyList[unitId]);
71    }
72
73    for (int unitId = 0; unitId < numSIMDs; ++unitId) {
74        waveStatusList.push_back(&computeUnit->waveStatusList[unitId]);
75    }
76
77    vectorAluInstAvail = &computeUnit->vectorAluInstAvail;
78    glbMemInstAvail= &computeUnit->glbMemInstAvail;
79    shrMemInstAvail= &computeUnit->shrMemInstAvail;
80}
81
82void
83ScoreboardCheckStage::initStatistics()
84{
85    lastGlbMemSimd = -1;
86    lastShrMemSimd = -1;
87    *glbMemInstAvail = 0;
88    *shrMemInstAvail = 0;
89
90    for (int unitId = 0; unitId < numSIMDs; ++unitId)
91        vectorAluInstAvail->at(unitId) = false;
92}
93
94void
95ScoreboardCheckStage::collectStatistics(Wavefront *curWave, int unitId)
96{
97    if (curWave->instructionBuffer.empty())
98        return;
99
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();
104
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;
113    }
114
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;
123    }
124}
125
126void
127ScoreboardCheckStage::exec()
128{
129    initStatistics();
130
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();
135    }
136
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);
144
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)) {
150                    continue;
151                }
152
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;
164            }
165        }
166    }
167}
168
169void
170ScoreboardCheckStage::regStats()
171{
172}
173