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 * 1712697Santhony.gutierrez@amd.com * 3. Neither the name of the copyright holder nor the names of its 1812697Santhony.gutierrez@amd.com * contributors may be used to endorse or promote products derived from this 1912697Santhony.gutierrez@amd.com * software 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 * 3312697Santhony.gutierrez@amd.com * Authors: John Kalamatianos, 3412697Santhony.gutierrez@amd.com * Sooraj Puthoor, 3512697Santhony.gutierrez@amd.com * Mark Wyse 3611308Santhony.gutierrez@amd.com */ 3711308Santhony.gutierrez@amd.com 3811308Santhony.gutierrez@amd.com#include "gpu-compute/schedule_stage.hh" 3911308Santhony.gutierrez@amd.com 4011308Santhony.gutierrez@amd.com#include "gpu-compute/compute_unit.hh" 4111308Santhony.gutierrez@amd.com#include "gpu-compute/gpu_static_inst.hh" 4211308Santhony.gutierrez@amd.com#include "gpu-compute/vector_register_file.hh" 4311308Santhony.gutierrez@amd.com#include "gpu-compute/wavefront.hh" 4411308Santhony.gutierrez@amd.com 4511308Santhony.gutierrez@amd.comScheduleStage::ScheduleStage(const ComputeUnitParams *p) 4611308Santhony.gutierrez@amd.com : numSIMDs(p->num_SIMDs), 4711308Santhony.gutierrez@amd.com numMemUnits(p->num_global_mem_pipes + p->num_shared_mem_pipes) 4811308Santhony.gutierrez@amd.com{ 4911308Santhony.gutierrez@amd.com for (int j = 0; j < numSIMDs + numMemUnits; ++j) { 5012696Santhony.gutierrez@amd.com scheduler.emplace_back(p); 5111308Santhony.gutierrez@amd.com } 5211308Santhony.gutierrez@amd.com} 5311308Santhony.gutierrez@amd.com 5411308Santhony.gutierrez@amd.comScheduleStage::~ScheduleStage() 5511308Santhony.gutierrez@amd.com{ 5611308Santhony.gutierrez@amd.com scheduler.clear(); 5711308Santhony.gutierrez@amd.com waveStatusList.clear(); 5811308Santhony.gutierrez@amd.com} 5911308Santhony.gutierrez@amd.com 6011308Santhony.gutierrez@amd.comvoid 6111308Santhony.gutierrez@amd.comScheduleStage::init(ComputeUnit *cu) 6211308Santhony.gutierrez@amd.com{ 6311308Santhony.gutierrez@amd.com computeUnit = cu; 6411308Santhony.gutierrez@amd.com _name = computeUnit->name() + ".ScheduleStage"; 6511308Santhony.gutierrez@amd.com 6611308Santhony.gutierrez@amd.com for (int j = 0; j < numSIMDs + numMemUnits; ++j) { 6711308Santhony.gutierrez@amd.com scheduler[j].bindList(&computeUnit->readyList[j]); 6811308Santhony.gutierrez@amd.com } 6911308Santhony.gutierrez@amd.com 7011308Santhony.gutierrez@amd.com for (int j = 0; j < numSIMDs; ++j) { 7111308Santhony.gutierrez@amd.com waveStatusList.push_back(&computeUnit->waveStatusList[j]); 7211308Santhony.gutierrez@amd.com } 7311308Santhony.gutierrez@amd.com 7411308Santhony.gutierrez@amd.com dispatchList = &computeUnit->dispatchList; 7511308Santhony.gutierrez@amd.com} 7611308Santhony.gutierrez@amd.com 7711308Santhony.gutierrez@amd.comvoid 7811308Santhony.gutierrez@amd.comScheduleStage::arbitrate() 7911308Santhony.gutierrez@amd.com{ 8011308Santhony.gutierrez@amd.com // iterate over all Memory pipelines 8111308Santhony.gutierrez@amd.com for (int j = numSIMDs; j < numSIMDs + numMemUnits; ++j) { 8211308Santhony.gutierrez@amd.com if (dispatchList->at(j).first) { 8311308Santhony.gutierrez@amd.com Wavefront *waveToMemPipe = dispatchList->at(j).first; 8411308Santhony.gutierrez@amd.com // iterate over all execution pipelines 8511308Santhony.gutierrez@amd.com for (int i = 0; i < numSIMDs + numMemUnits; ++i) { 8611308Santhony.gutierrez@amd.com if ((i != j) && (dispatchList->at(i).first)) { 8711308Santhony.gutierrez@amd.com Wavefront *waveToExePipe = dispatchList->at(i).first; 8811308Santhony.gutierrez@amd.com // if the two selected wavefronts are mapped to the same 8911308Santhony.gutierrez@amd.com // SIMD unit then they share the VRF 9011308Santhony.gutierrez@amd.com if (waveToMemPipe->simdId == waveToExePipe->simdId) { 9111308Santhony.gutierrez@amd.com int simdId = waveToMemPipe->simdId; 9211308Santhony.gutierrez@amd.com // Read VRF port arbitration: 9311308Santhony.gutierrez@amd.com // If there are read VRF port conflicts between the 9411308Santhony.gutierrez@amd.com // a memory and another instruction we drop the other 9511308Santhony.gutierrez@amd.com // instruction. We don't need to check for write VRF 9611308Santhony.gutierrez@amd.com // port conflicts because the memory instruction either 9711308Santhony.gutierrez@amd.com // does not need to write to the VRF (store) or will 9811308Santhony.gutierrez@amd.com // write to the VRF when the data comes back (load) in 9911308Santhony.gutierrez@amd.com // which case the arbiter of the memory pipes will 10011308Santhony.gutierrez@amd.com // resolve any conflicts 10111308Santhony.gutierrez@amd.com if (computeUnit->vrf[simdId]-> 10211308Santhony.gutierrez@amd.com isReadConflict(waveToMemPipe->wfSlotId, 10311308Santhony.gutierrez@amd.com waveToExePipe->wfSlotId)) { 10411308Santhony.gutierrez@amd.com // FIXME: The "second" member variable is never 10511308Santhony.gutierrez@amd.com // used in the model. I am setting it to READY 10611308Santhony.gutierrez@amd.com // simply to follow the protocol of setting it 10711308Santhony.gutierrez@amd.com // when the WF has an instruction ready to issue 10811308Santhony.gutierrez@amd.com waveStatusList[simdId]->at(waveToExePipe->wfSlotId) 10911308Santhony.gutierrez@amd.com .second = READY; 11011308Santhony.gutierrez@amd.com 11111308Santhony.gutierrez@amd.com dispatchList->at(i).first = nullptr; 11211308Santhony.gutierrez@amd.com dispatchList->at(i).second = EMPTY; 11311308Santhony.gutierrez@amd.com break; 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.com} 12111308Santhony.gutierrez@amd.com 12211308Santhony.gutierrez@amd.comvoid 12311308Santhony.gutierrez@amd.comScheduleStage::exec() 12411308Santhony.gutierrez@amd.com{ 12511308Santhony.gutierrez@amd.com for (int j = 0; j < numSIMDs + numMemUnits; ++j) { 12611308Santhony.gutierrez@amd.com uint32_t readyListSize = computeUnit->readyList[j].size(); 12711308Santhony.gutierrez@amd.com 12811308Santhony.gutierrez@amd.com // If no wave is ready to be scheduled on the execution resource 12911308Santhony.gutierrez@amd.com // then skip scheduling for this execution resource 13011308Santhony.gutierrez@amd.com if (!readyListSize) { 13111308Santhony.gutierrez@amd.com continue; 13211308Santhony.gutierrez@amd.com } 13311308Santhony.gutierrez@amd.com 13411308Santhony.gutierrez@amd.com Wavefront *waveToBeDispatched = scheduler[j].chooseWave(); 13511308Santhony.gutierrez@amd.com dispatchList->at(j).first = waveToBeDispatched; 13611308Santhony.gutierrez@amd.com waveToBeDispatched->updateResources(); 13711308Santhony.gutierrez@amd.com dispatchList->at(j).second = FILLED; 13811308Santhony.gutierrez@amd.com 13911308Santhony.gutierrez@amd.com waveStatusList[waveToBeDispatched->simdId]->at( 14011308Santhony.gutierrez@amd.com waveToBeDispatched->wfSlotId).second = BLOCKED; 14111308Santhony.gutierrez@amd.com 14211308Santhony.gutierrez@amd.com assert(computeUnit->readyList[j].size() == readyListSize - 1); 14311308Santhony.gutierrez@amd.com } 14411308Santhony.gutierrez@amd.com // arbitrate over all shared resources among instructions being issued 14511308Santhony.gutierrez@amd.com // simultaneously 14611308Santhony.gutierrez@amd.com arbitrate(); 14711308Santhony.gutierrez@amd.com} 14811308Santhony.gutierrez@amd.com 14911308Santhony.gutierrez@amd.comvoid 15011308Santhony.gutierrez@amd.comScheduleStage::regStats() 15111308Santhony.gutierrez@amd.com{ 15211308Santhony.gutierrez@amd.com} 153