schedule_stage.cc revision 12696
111308Santhony.gutierrez@amd.com/* 211308Santhony.gutierrez@amd.com * Copyright (c) 2014-2015 Advanced Micro Devices, Inc. 311308Santhony.gutierrez@amd.com * All rights reserved. 411308Santhony.gutierrez@amd.com * 511308Santhony.gutierrez@amd.com * For use for simulation and test purposes only 611308Santhony.gutierrez@amd.com * 711308Santhony.gutierrez@amd.com * Redistribution and use in source and binary forms, with or without 811308Santhony.gutierrez@amd.com * modification, are permitted provided that the following conditions are met: 911308Santhony.gutierrez@amd.com * 1011308Santhony.gutierrez@amd.com * 1. Redistributions of source code must retain the above copyright notice, 1111308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer. 1211308Santhony.gutierrez@amd.com * 1311308Santhony.gutierrez@amd.com * 2. Redistributions in binary form must reproduce the above copyright notice, 1411308Santhony.gutierrez@amd.com * this list of conditions and the following disclaimer in the documentation 1511308Santhony.gutierrez@amd.com * and/or other materials provided with the distribution. 1611308Santhony.gutierrez@amd.com * 1711308Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its contributors 1811308Santhony.gutierrez@amd.com * may be used to endorse or promote products derived from this software 1911308Santhony.gutierrez@amd.com * without specific prior written permission. 2011308Santhony.gutierrez@amd.com * 2111308Santhony.gutierrez@amd.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 2211308Santhony.gutierrez@amd.com * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2311308Santhony.gutierrez@amd.com * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2411308Santhony.gutierrez@amd.com * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 2511308Santhony.gutierrez@amd.com * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2611308Santhony.gutierrez@amd.com * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2711308Santhony.gutierrez@amd.com * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2811308Santhony.gutierrez@amd.com * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2911308Santhony.gutierrez@amd.com * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 3011308Santhony.gutierrez@amd.com * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 3111308Santhony.gutierrez@amd.com * POSSIBILITY OF SUCH DAMAGE. 3211308Santhony.gutierrez@amd.com * 3311308Santhony.gutierrez@amd.com * Author: Sooraj Puthoor 3411308Santhony.gutierrez@amd.com */ 3511308Santhony.gutierrez@amd.com 3611308Santhony.gutierrez@amd.com#include "gpu-compute/schedule_stage.hh" 3711308Santhony.gutierrez@amd.com 3811308Santhony.gutierrez@amd.com#include "gpu-compute/compute_unit.hh" 3911308Santhony.gutierrez@amd.com#include "gpu-compute/gpu_static_inst.hh" 4011308Santhony.gutierrez@amd.com#include "gpu-compute/vector_register_file.hh" 4111308Santhony.gutierrez@amd.com#include "gpu-compute/wavefront.hh" 4211308Santhony.gutierrez@amd.com 4311308Santhony.gutierrez@amd.comScheduleStage::ScheduleStage(const ComputeUnitParams *p) 4411308Santhony.gutierrez@amd.com : numSIMDs(p->num_SIMDs), 4511308Santhony.gutierrez@amd.com numMemUnits(p->num_global_mem_pipes + p->num_shared_mem_pipes) 4611308Santhony.gutierrez@amd.com{ 4711308Santhony.gutierrez@amd.com for (int j = 0; j < numSIMDs + numMemUnits; ++j) { 4812696Santhony.gutierrez@amd.com scheduler.emplace_back(p); 4911308Santhony.gutierrez@amd.com } 5011308Santhony.gutierrez@amd.com} 5111308Santhony.gutierrez@amd.com 5211308Santhony.gutierrez@amd.comScheduleStage::~ScheduleStage() 5311308Santhony.gutierrez@amd.com{ 5411308Santhony.gutierrez@amd.com scheduler.clear(); 5511308Santhony.gutierrez@amd.com waveStatusList.clear(); 5611308Santhony.gutierrez@amd.com} 5711308Santhony.gutierrez@amd.com 5811308Santhony.gutierrez@amd.comvoid 5911308Santhony.gutierrez@amd.comScheduleStage::init(ComputeUnit *cu) 6011308Santhony.gutierrez@amd.com{ 6111308Santhony.gutierrez@amd.com computeUnit = cu; 6211308Santhony.gutierrez@amd.com _name = computeUnit->name() + ".ScheduleStage"; 6311308Santhony.gutierrez@amd.com 6411308Santhony.gutierrez@amd.com for (int j = 0; j < numSIMDs + numMemUnits; ++j) { 6511308Santhony.gutierrez@amd.com scheduler[j].bindList(&computeUnit->readyList[j]); 6611308Santhony.gutierrez@amd.com } 6711308Santhony.gutierrez@amd.com 6811308Santhony.gutierrez@amd.com for (int j = 0; j < numSIMDs; ++j) { 6911308Santhony.gutierrez@amd.com waveStatusList.push_back(&computeUnit->waveStatusList[j]); 7011308Santhony.gutierrez@amd.com } 7111308Santhony.gutierrez@amd.com 7211308Santhony.gutierrez@amd.com dispatchList = &computeUnit->dispatchList; 7311308Santhony.gutierrez@amd.com} 7411308Santhony.gutierrez@amd.com 7511308Santhony.gutierrez@amd.comvoid 7611308Santhony.gutierrez@amd.comScheduleStage::arbitrate() 7711308Santhony.gutierrez@amd.com{ 7811308Santhony.gutierrez@amd.com // iterate over all Memory pipelines 7911308Santhony.gutierrez@amd.com for (int j = numSIMDs; j < numSIMDs + numMemUnits; ++j) { 8011308Santhony.gutierrez@amd.com if (dispatchList->at(j).first) { 8111308Santhony.gutierrez@amd.com Wavefront *waveToMemPipe = dispatchList->at(j).first; 8211308Santhony.gutierrez@amd.com // iterate over all execution pipelines 8311308Santhony.gutierrez@amd.com for (int i = 0; i < numSIMDs + numMemUnits; ++i) { 8411308Santhony.gutierrez@amd.com if ((i != j) && (dispatchList->at(i).first)) { 8511308Santhony.gutierrez@amd.com Wavefront *waveToExePipe = dispatchList->at(i).first; 8611308Santhony.gutierrez@amd.com // if the two selected wavefronts are mapped to the same 8711308Santhony.gutierrez@amd.com // SIMD unit then they share the VRF 8811308Santhony.gutierrez@amd.com if (waveToMemPipe->simdId == waveToExePipe->simdId) { 8911308Santhony.gutierrez@amd.com int simdId = waveToMemPipe->simdId; 9011308Santhony.gutierrez@amd.com // Read VRF port arbitration: 9111308Santhony.gutierrez@amd.com // If there are read VRF port conflicts between the 9211308Santhony.gutierrez@amd.com // a memory and another instruction we drop the other 9311308Santhony.gutierrez@amd.com // instruction. We don't need to check for write VRF 9411308Santhony.gutierrez@amd.com // port conflicts because the memory instruction either 9511308Santhony.gutierrez@amd.com // does not need to write to the VRF (store) or will 9611308Santhony.gutierrez@amd.com // write to the VRF when the data comes back (load) in 9711308Santhony.gutierrez@amd.com // which case the arbiter of the memory pipes will 9811308Santhony.gutierrez@amd.com // resolve any conflicts 9911308Santhony.gutierrez@amd.com if (computeUnit->vrf[simdId]-> 10011308Santhony.gutierrez@amd.com isReadConflict(waveToMemPipe->wfSlotId, 10111308Santhony.gutierrez@amd.com waveToExePipe->wfSlotId)) { 10211308Santhony.gutierrez@amd.com // FIXME: The "second" member variable is never 10311308Santhony.gutierrez@amd.com // used in the model. I am setting it to READY 10411308Santhony.gutierrez@amd.com // simply to follow the protocol of setting it 10511308Santhony.gutierrez@amd.com // when the WF has an instruction ready to issue 10611308Santhony.gutierrez@amd.com waveStatusList[simdId]->at(waveToExePipe->wfSlotId) 10711308Santhony.gutierrez@amd.com .second = READY; 10811308Santhony.gutierrez@amd.com 10911308Santhony.gutierrez@amd.com dispatchList->at(i).first = nullptr; 11011308Santhony.gutierrez@amd.com dispatchList->at(i).second = EMPTY; 11111308Santhony.gutierrez@amd.com break; 11211308Santhony.gutierrez@amd.com } 11311308Santhony.gutierrez@amd.com } 11411308Santhony.gutierrez@amd.com } 11511308Santhony.gutierrez@amd.com } 11611308Santhony.gutierrez@amd.com } 11711308Santhony.gutierrez@amd.com } 11811308Santhony.gutierrez@amd.com} 11911308Santhony.gutierrez@amd.com 12011308Santhony.gutierrez@amd.comvoid 12111308Santhony.gutierrez@amd.comScheduleStage::exec() 12211308Santhony.gutierrez@amd.com{ 12311308Santhony.gutierrez@amd.com for (int j = 0; j < numSIMDs + numMemUnits; ++j) { 12411308Santhony.gutierrez@amd.com uint32_t readyListSize = computeUnit->readyList[j].size(); 12511308Santhony.gutierrez@amd.com 12611308Santhony.gutierrez@amd.com // If no wave is ready to be scheduled on the execution resource 12711308Santhony.gutierrez@amd.com // then skip scheduling for this execution resource 12811308Santhony.gutierrez@amd.com if (!readyListSize) { 12911308Santhony.gutierrez@amd.com continue; 13011308Santhony.gutierrez@amd.com } 13111308Santhony.gutierrez@amd.com 13211308Santhony.gutierrez@amd.com Wavefront *waveToBeDispatched = scheduler[j].chooseWave(); 13311308Santhony.gutierrez@amd.com dispatchList->at(j).first = waveToBeDispatched; 13411308Santhony.gutierrez@amd.com waveToBeDispatched->updateResources(); 13511308Santhony.gutierrez@amd.com dispatchList->at(j).second = FILLED; 13611308Santhony.gutierrez@amd.com 13711308Santhony.gutierrez@amd.com waveStatusList[waveToBeDispatched->simdId]->at( 13811308Santhony.gutierrez@amd.com waveToBeDispatched->wfSlotId).second = BLOCKED; 13911308Santhony.gutierrez@amd.com 14011308Santhony.gutierrez@amd.com assert(computeUnit->readyList[j].size() == readyListSize - 1); 14111308Santhony.gutierrez@amd.com } 14211308Santhony.gutierrez@amd.com // arbitrate over all shared resources among instructions being issued 14311308Santhony.gutierrez@amd.com // simultaneously 14411308Santhony.gutierrez@amd.com arbitrate(); 14511308Santhony.gutierrez@amd.com} 14611308Santhony.gutierrez@amd.com 14711308Santhony.gutierrez@amd.comvoid 14811308Santhony.gutierrez@amd.comScheduleStage::regStats() 14911308Santhony.gutierrez@amd.com{ 15011308Santhony.gutierrez@amd.com} 151