gpu_dyn_inst.cc revision 11534:7106f550afad
1/*
2 * Copyright (c) 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: Anthony Gutierrez
34 */
35
36#include "gpu-compute/gpu_dyn_inst.hh"
37
38#include "debug/GPUMem.hh"
39#include "gpu-compute/gpu_static_inst.hh"
40#include "gpu-compute/shader.hh"
41#include "gpu-compute/wavefront.hh"
42
43GPUDynInst::GPUDynInst(ComputeUnit *_cu, Wavefront *_wf,
44                       GPUStaticInst *_staticInst, uint64_t instSeqNum)
45    : GPUExecContext(_cu, _wf), addr(computeUnit()->wfSize(), (Addr)0),
46      m_op(Enums::MO_UNDEF),
47      memoryOrder(Enums::MEMORY_ORDER_NONE), n_reg(0), useContinuation(false),
48      statusBitVector(0), staticInst(_staticInst), _seqNum(instSeqNum)
49{
50    tlbHitLevel.assign(computeUnit()->wfSize(), -1);
51    d_data = new uint8_t[computeUnit()->wfSize() * 16];
52    a_data = new uint8_t[computeUnit()->wfSize() * 8];
53    x_data = new uint8_t[computeUnit()->wfSize() * 8];
54    for (int i = 0; i < (computeUnit()->wfSize() * 8); ++i) {
55        a_data[i] = 0;
56        x_data[i] = 0;
57    }
58    for (int i = 0; i < (computeUnit()->wfSize() * 16); ++i) {
59        d_data[i] = 0;
60    }
61}
62
63GPUDynInst::~GPUDynInst()
64{
65    delete[] d_data;
66    delete[] a_data;
67    delete[] x_data;
68}
69
70void
71GPUDynInst::execute()
72{
73    GPUDynInstPtr gpuDynInst = std::make_shared<GPUDynInst>(cu, wf, staticInst,
74                                                            _seqNum);
75    staticInst->execute(gpuDynInst);
76}
77
78int
79GPUDynInst::numSrcRegOperands()
80{
81    return staticInst->numSrcRegOperands();
82}
83
84int
85GPUDynInst::numDstRegOperands()
86{
87    return staticInst->numDstRegOperands();
88}
89
90int
91GPUDynInst::getNumOperands()
92{
93    return staticInst->getNumOperands();
94}
95
96bool
97GPUDynInst::isVectorRegister(int operandIdx)
98{
99    return staticInst->isVectorRegister(operandIdx);
100}
101
102bool
103GPUDynInst::isScalarRegister(int operandIdx)
104{
105    return staticInst->isScalarRegister(operandIdx);
106}
107
108int
109GPUDynInst::getRegisterIndex(int operandIdx)
110{
111    return staticInst->getRegisterIndex(operandIdx);
112}
113
114int
115GPUDynInst::getOperandSize(int operandIdx)
116{
117    return staticInst->getOperandSize(operandIdx);
118}
119
120bool
121GPUDynInst::isDstOperand(int operandIdx)
122{
123    return staticInst->isDstOperand(operandIdx);
124}
125
126bool
127GPUDynInst::isSrcOperand(int operandIdx)
128{
129    return staticInst->isSrcOperand(operandIdx);
130}
131
132bool
133GPUDynInst::isArgLoad()
134{
135    return staticInst->isArgLoad();
136}
137
138const std::string&
139GPUDynInst::disassemble() const
140{
141    return staticInst->disassemble();
142}
143
144uint64_t
145GPUDynInst::seqNum() const
146{
147    return _seqNum;
148}
149
150Enums::OpType
151GPUDynInst::opType()
152{
153    return staticInst->o_type;
154}
155
156Enums::StorageClassType
157GPUDynInst::executedAs()
158{
159    return staticInst->executed_as;
160}
161
162// Process a memory instruction and (if necessary) submit timing request
163void
164GPUDynInst::initiateAcc(GPUDynInstPtr gpuDynInst)
165{
166    DPRINTF(GPUMem, "CU%d: WF[%d][%d]: mempacket status bitvector=%#x\n",
167            cu->cu_id, simdId, wfSlotId, exec_mask);
168
169    staticInst->initiateAcc(gpuDynInst);
170    time = 0;
171}
172
173bool
174GPUDynInst::scalarOp() const
175{
176    return staticInst->scalarOp();
177}
178
179void
180GPUDynInst::updateStats()
181{
182    if (staticInst->isLocalMem()) {
183        // access to LDS (shared) memory
184        cu->dynamicLMemInstrCnt++;
185    } else {
186        // access to global memory
187
188        // update PageDivergence histogram
189        int number_pages_touched = cu->pagesTouched.size();
190        assert(number_pages_touched);
191        cu->pageDivergenceDist.sample(number_pages_touched);
192
193        std::pair<ComputeUnit::pageDataStruct::iterator, bool> ret;
194
195        for (auto it : cu->pagesTouched) {
196            // see if this page has been touched before. if not, this also
197            // inserts the page into the table.
198            ret = cu->pageAccesses
199                .insert(ComputeUnit::pageDataStruct::value_type(it.first,
200                        std::make_pair(1, it.second)));
201
202            // if yes, then update the stats
203            if (!ret.second) {
204                ret.first->second.first++;
205                ret.first->second.second += it.second;
206            }
207        }
208
209        cu->pagesTouched.clear();
210
211        // total number of memory instructions (dynamic)
212        // Atomics are counted as a single memory instruction.
213        // this is # memory instructions per wavefronts, not per workitem
214        cu->dynamicGMemInstrCnt++;
215    }
216}
217