schedule_stage.cc revision 12696:15d4edfbb01b
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/schedule_stage.hh"
37
38#include "gpu-compute/compute_unit.hh"
39#include "gpu-compute/gpu_static_inst.hh"
40#include "gpu-compute/vector_register_file.hh"
41#include "gpu-compute/wavefront.hh"
42
43ScheduleStage::ScheduleStage(const ComputeUnitParams *p)
44    : numSIMDs(p->num_SIMDs),
45      numMemUnits(p->num_global_mem_pipes + p->num_shared_mem_pipes)
46{
47    for (int j = 0; j < numSIMDs + numMemUnits; ++j) {
48        scheduler.emplace_back(p);
49    }
50}
51
52ScheduleStage::~ScheduleStage()
53{
54    scheduler.clear();
55    waveStatusList.clear();
56}
57
58void
59ScheduleStage::init(ComputeUnit *cu)
60{
61    computeUnit = cu;
62    _name = computeUnit->name() + ".ScheduleStage";
63
64    for (int j = 0; j < numSIMDs + numMemUnits; ++j) {
65        scheduler[j].bindList(&computeUnit->readyList[j]);
66    }
67
68    for (int j = 0; j < numSIMDs; ++j) {
69        waveStatusList.push_back(&computeUnit->waveStatusList[j]);
70    }
71
72    dispatchList = &computeUnit->dispatchList;
73}
74
75void
76ScheduleStage::arbitrate()
77{
78    // iterate over all Memory pipelines
79    for (int j = numSIMDs; j < numSIMDs + numMemUnits; ++j) {
80        if (dispatchList->at(j).first) {
81            Wavefront *waveToMemPipe = dispatchList->at(j).first;
82            // iterate over all execution pipelines
83            for (int i = 0; i < numSIMDs + numMemUnits; ++i) {
84                if ((i != j) && (dispatchList->at(i).first)) {
85                    Wavefront *waveToExePipe = dispatchList->at(i).first;
86                    // if the two selected wavefronts are mapped to the same
87                    // SIMD unit then they share the VRF
88                    if (waveToMemPipe->simdId == waveToExePipe->simdId) {
89                        int simdId = waveToMemPipe->simdId;
90                        // Read VRF port arbitration:
91                        // If there are read VRF port conflicts between the
92                        // a memory and another instruction we drop the other
93                        // instruction. We don't need to check for write VRF
94                        // port conflicts because the memory instruction either
95                        // does not need to write to the VRF (store) or will
96                        // write to the VRF when the data comes back (load) in
97                        // which case the arbiter of the memory pipes will
98                        // resolve any conflicts
99                        if (computeUnit->vrf[simdId]->
100                            isReadConflict(waveToMemPipe->wfSlotId,
101                            waveToExePipe->wfSlotId)) {
102                            // FIXME: The "second" member variable is never
103                            // used in the model. I am setting it to READY
104                            // simply to follow the protocol of setting it
105                            // when the WF has an instruction ready to issue
106                            waveStatusList[simdId]->at(waveToExePipe->wfSlotId)
107                                                    .second = READY;
108
109                            dispatchList->at(i).first = nullptr;
110                            dispatchList->at(i).second = EMPTY;
111                            break;
112                        }
113                    }
114                }
115            }
116        }
117    }
118}
119
120void
121ScheduleStage::exec()
122{
123    for (int j = 0; j < numSIMDs + numMemUnits; ++j) {
124         uint32_t readyListSize = computeUnit->readyList[j].size();
125
126         // If no wave is ready to be scheduled on the execution resource
127         // then skip scheduling for this execution resource
128         if (!readyListSize) {
129             continue;
130         }
131
132         Wavefront *waveToBeDispatched = scheduler[j].chooseWave();
133         dispatchList->at(j).first = waveToBeDispatched;
134         waveToBeDispatched->updateResources();
135         dispatchList->at(j).second = FILLED;
136
137         waveStatusList[waveToBeDispatched->simdId]->at(
138                 waveToBeDispatched->wfSlotId).second = BLOCKED;
139
140         assert(computeUnit->readyList[j].size() == readyListSize - 1);
141    }
142    // arbitrate over all shared resources among instructions being issued
143    // simultaneously
144    arbitrate();
145}
146
147void
148ScheduleStage::regStats()
149{
150}
151