diff options
119 files changed, 10094 insertions, 2860 deletions
diff --git a/.github/workflows/accelsim.yml b/.github/workflows/accelsim.yml new file mode 100644 index 0000000..7410352 --- /dev/null +++ b/.github/workflows/accelsim.yml @@ -0,0 +1,33 @@ +# Test backend changes with Accel-Sim + +name: Short-Tests-AccelSim + +# Controls when the workflow will run +on: + push: + branches-ignore: + - "gh-readonly-queue**" + merge_group: + pull_request: + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# By default regress against accel-sim's dev branch +env: + ACCELSIM_BRANCH: dev + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + build-QV100: + runs-on: ubuntu-latest + container: + image: tgrogers/accel-sim_regress:Ubuntu-22.04-cuda-11.7 + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - name: Run Simulation + run: /bin/bash $GITHUB_WORKSPACE/short-tests-accelsim.sh + diff --git a/.github/workflows/cmake.yml b/.github/workflows/cmake.yml new file mode 100644 index 0000000..c0a22eb --- /dev/null +++ b/.github/workflows/cmake.yml @@ -0,0 +1,86 @@ +# Workflow with cmake build system +name: Short-Tests-CMake + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the mydev branch + push: + branches-ignore: + - "gh-readonly-queue**" + merge_group: + pull_request: + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + build-TITANV: + runs-on: ubuntu-latest + container: + image: tgrogers/accel-sim_regress:Ubuntu-22.04-cuda-11.7 + env: + CONFIG: TITANV + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - name: Run Simulation + run: /bin/bash $GITHUB_WORKSPACE/short-tests-cmake.sh + + build-TITANV-LOCALXBAR: + runs-on: ubuntu-latest + container: + image: tgrogers/accel-sim_regress:Ubuntu-22.04-cuda-11.7 + env: + CONFIG: TITANV-LOCALXBAR + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - name: Run Simulation + run: /bin/bash $GITHUB_WORKSPACE/short-tests-cmake.sh + + build-QV100: + runs-on: ubuntu-latest + container: + image: tgrogers/accel-sim_regress:Ubuntu-22.04-cuda-11.7 + env: + CONFIG: QV100 + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - name: Run Simulation + run: /bin/bash $GITHUB_WORKSPACE/short-tests-cmake.sh + + build-2060: + runs-on: ubuntu-latest + container: + image: tgrogers/accel-sim_regress:Ubuntu-22.04-cuda-11.7 + env: + CONFIG: RTX2060 + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - name: Run Simulation + run: /bin/bash $GITHUB_WORKSPACE/short-tests-cmake.sh + + build-3070: + runs-on: ubuntu-latest + container: + image: tgrogers/accel-sim_regress:Ubuntu-22.04-cuda-11.7 + env: + CONFIG: RTX3070 + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - name: Run Simulation + run: /bin/bash $GITHUB_WORKSPACE/short-tests-cmake.sh diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 0000000..8e0ae23 --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,105 @@ +# This is a basic workflow to help you get started with Actions + +name: Short-Tests + +# Controls when the workflow will run +on: + push: + branches-ignore: + - "gh-readonly-queue**" + merge_group: + pull_request: + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + build-TITANV: + runs-on: ubuntu-latest + container: + image: tgrogers/accel-sim_regress:Ubuntu-22.04-cuda-11.7 + env: + CONFIG: TITANV + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - name: Run Simulation + run: /bin/bash $GITHUB_WORKSPACE/short-tests.sh + + build-TITANV-LOCALXBAR: + runs-on: ubuntu-latest + container: + image: tgrogers/accel-sim_regress:Ubuntu-22.04-cuda-11.7 + env: + CONFIG: TITANV-LOCALXBAR + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - name: Run Simulation + run: /bin/bash $GITHUB_WORKSPACE/short-tests.sh + + build-QV100: + runs-on: ubuntu-latest + container: + image: tgrogers/accel-sim_regress:Ubuntu-22.04-cuda-11.7 + env: + CONFIG: QV100 + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - name: Run Simulation + run: /bin/bash $GITHUB_WORKSPACE/short-tests.sh + + build-2060: + runs-on: ubuntu-latest + container: + image: tgrogers/accel-sim_regress:Ubuntu-22.04-cuda-11.7 + env: + CONFIG: RTX2060 + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - name: Run Simulation + run: /bin/bash $GITHUB_WORKSPACE/short-tests.sh + + build-3070: + runs-on: ubuntu-latest + container: + image: tgrogers/accel-sim_regress:Ubuntu-22.04-cuda-11.7 + env: + CONFIG: RTX3070 + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - name: Run Simulation + run: /bin/bash $GITHUB_WORKSPACE/short-tests.sh + format-code: + if: github.event_name == 'pull_request' + runs-on: tgrogers-raid + needs: [build-TITANV, build-TITANV-LOCALXBAR, build-QV100, build-2060, build-3070] + steps: + - uses: actions/checkout@v4 + with: + ref: ${{github.event.pull_request.head.ref}} + repository: ${{github.event.pull_request.head.repo.full_name}} + ssh-key: '' + + - name: Run clang-format + run: | + git config user.name "purdue-jenkins" + git config user.email "[email protected]" + git remote set-url origin [email protected]:${{github.event.pull_request.head.repo.full_name}} + git remote -v + /bin/bash ./format-code.sh + if git status --untracked-files=no | grep -q "nothing to commit"; then echo "No changes to commit."; else git commit -a -m "Automated Format"; git push; fi diff --git a/.github/workflows/sst_integration.yml b/.github/workflows/sst_integration.yml new file mode 100644 index 0000000..03635db --- /dev/null +++ b/.github/workflows/sst_integration.yml @@ -0,0 +1,80 @@ +# Workflow with cmake build system +name: SST Integration Test + +# Controls when the workflow will run +on: + # Triggers the workflow on push or pull request events but only for the mydev branch + push: + branches-ignore: + - "gh-readonly-queue**" + pull_request: + + # Allows you to run this workflow manually from the Actions tab + workflow_dispatch: + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + build-QV100: + runs-on: ubuntu-latest + defaults: + run: + shell: bash + strategy: + matrix: + # test_type: [simple, medium, long] + test_type: [simple, medium] + container: + image: tgrogers/accel-sim_regress:SST-Integration-Ubuntu-22.04-cuda-11.7-llvm-18.1.8-riscv-gnu-2024.08.06-nightly + env: + CONFIG: QV100 + GPU_ARCH: sm_70 + + # Steps represent a sequence of tasks that will be executed as part of the job + steps: + # Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it + - uses: actions/checkout@v4 + - name: Build GPGPU-Sim in SST mode + run: | + source ./setup_environment + make -j4 + - name: Prepare SST dependencies + run: | + apt install -y openmpi-bin openmpi-common libtool libtool-bin autoconf python3 python3-dev automake build-essential git + # Use personal repo for now + - name: Build SST-Core + run: | + git clone https://github.com/William-An/sst-core.git + cd sst-core + git pull + git checkout devel + ./autogen.sh + ./configure --prefix=`realpath ../sstcore-install` --disable-mpi --disable-mem-pools + make -j4 + make install + cd .. + rm -rf ./sst-core + # Use personal repo for now + - name: Build SST-Elements + run: | + git clone https://github.com/William-An/sst-elements.git + source ./setup_environment + cd sst-elements + git pull + git checkout balar-mmio-vanadis-llvm + ./autogen.sh + ./configure --prefix=`realpath ../sstelements-install` --with-sst-core=`realpath ../sstcore-install` --with-cuda=$CUDA_INSTALL_PATH --with-gpgpusim=$GPGPUSIM_ROOT + make -j4 + make install + # Have to resource the gpu app + # Also fake a SDK since rodinia 2.0 does not need this, speed things up on github + - name: Balar Test + run: | + pip install testtools blessings pygments + source ./setup_environment + mkdir 4.2 + mkdir fake_sdk + export NVIDIA_COMPUTE_SDK_LOCATION=$(readlink -f ./fake_sdk) + source $GPUAPPS_ROOT/src/setup_environment sst + rm -rf 4.2 + rm -f gpucomputingsdk_4.2.9_linux.run + ./sstcore-install/bin/sst-test-elements -w "*balar*${{ matrix.test_type }}*"
\ No newline at end of file @@ -61,3 +61,4 @@ debug_tools/WatchYourStep/ptxjitplus/*.ptx accel-sim-framework/ gpu-app-collection/ +setup diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..95ca8e0 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,167 @@ +cmake_minimum_required(VERSION 3.17) + +# Project name and version +project(GPGPU-Sim + VERSION 4.2.0 + DESCRIPTION "cycle-level simulator modeling contemporary graphics processing units (GPUs)" + HOMEPAGE_URL https://github.com/accel-sim/gpgpu-sim_distribution + LANGUAGES CXX) + +# Specify the C++ standard +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED True) + +# GPGPU-Sim build option +option(GPGPUSIM_ENABLE_TRACE "Whether to enable GPGPU-Sim debug tracing" ON) + +# GPGPU-Sim conditional build variable +set(GPGPUSIM_USE_POWER_MODEL OFF) +set(GPGPUSIM_USE_OPENCL OFF) + +# Check for dependencies +include(gpgpusim_check.cmake) + +# Create version file +add_custom_target(gen_build_string ALL + COMMAND ${CMAKE_COMMAND} -D INPUT_DIR=${CMAKE_CURRENT_SOURCE_DIR} -D OUTPUT_DIR=${CMAKE_BINARY_DIR} -P ${CMAKE_CURRENT_SOURCE_DIR}/gpgpusim_gen_build_string.cmake + COMMENT "Generating build string file to ${CMAKE_CURRENT_BINARY_DIR}") + +# CMake target +# GPGPU-Sim CUDA Runtime lib +# Use the entrypoint object files sources else CMake will complain +add_library(cudart SHARED $<TARGET_OBJECTS:gpgpusim_entrypoint>) +add_library(entrypoint STATIC $<TARGET_OBJECTS:gpgpusim_entrypoint>) + +# Add global C/CXX compilation flags and definitions +# TODO Specify more build modes like gem5 with fast opt? +if(${CMAKE_BUILD_TYPE} STREQUAL "Debug") + add_compile_definitions(DEBUG=1) + add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:-Wall;-Wno-unused-function;-Wno-sign-compare;-g;-fPIC>") + add_compile_options("$<$<COMPILE_LANGUAGE:C>:-Wall;-Wno-unused-function;-Wno-sign-compare;-ggdb;-fPIC>") +else() + add_compile_definitions(DEBUG=0) + add_compile_options("$<$<COMPILE_LANGUAGE:CXX>:-O3;-g;-Wall;-Wno-unused-function;-Wno-sign-compare;-fPIC>") + add_compile_options("$<$<COMPILE_LANGUAGE:C>:-Wall;-Wno-unused-function;-Wno-sign-compare;-fPIC>") +endif() + +# Add CUDA version +add_compile_definitions(CUDART_VERSION=${CUDA_VERSION_NUMBER}) + +# OpenCL support +if(GPGPUSIM_USE_OPENCL) + add_compile_definitions(OPENGL_SUPPORT) +endif() + +# Tracing support +if(GPGPUSIM_ENABLE_TRACE) + add_compile_definitions(TRACING_ON=1) +endif() + +# Add subdirectory +add_subdirectory(src) +add_subdirectory(libcuda) +add_subdirectory(libopencl) + +# Set linker option for libcudart.so +if(APPLE) + target_link_options(cudart PUBLIC "-Wl,-headerpad_max_install_names,-undefined,dynamic_lookup,-compatibility_version,1.1,-current_version,1.1;-lm;-lz;-pthread") +else() + target_link_options(cudart PUBLIC + "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/linux-so-version.txt;-lm;-lz;-lGL;-pthread") + target_link_options(entrypoint PUBLIC + "-Wl,--version-script=${CMAKE_CURRENT_SOURCE_DIR}/linux-so-version.txt;-lm;-lz;-lGL;-pthread") +endif() +# cuda: CUDA API lib +# ptxsim: cuda-sim, functional simulator +# gpgpusim: gpu simulator (gpgpu-sim) +# intersim: interconnect simulator +# accelwattch: power simulator +# Rest of source files in src/ will be created with gpgpusim_entrypoint target +target_link_libraries(cudart PUBLIC cuda ptxsim gpgpusim intersim) +target_link_libraries(entrypoint PUBLIC cuda ptxsim gpgpusim intersim) +if(GPGPUSIM_USE_POWER_MODEL) +target_link_libraries(cudart PUBLIC cuda ptxsim gpgpusim intersim accelwattch) +target_link_libraries(entrypoint PUBLIC cuda ptxsim gpgpusim intersim accelwattch) +endif() + +# TODO Conditionally build for Opencl? +# if(GPGPUSIM_USE_OPENCL) +# add_library(OpenCL) +# endif() + +# Install and post-install +# Get configure +set(GPGPUSIM_CONFIG "gcc-${CMAKE_CXX_COMPILER_VERSION}/cuda-${CUDA_VERSION_NUMBER}/${GPGPUSIM_BUILD_MODE}") + +# Env var setup script +include(gpgpusim_gen_setup_environment.cmake) + +# Installation +set(GPGPUSIM_INSTALL_PATH ${PROJECT_SOURCE_DIR}/lib/${GPGPUSIM_CONFIG}) +install(TARGETS cudart DESTINATION ${GPGPUSIM_INSTALL_PATH}) + +# Installing symlinks +install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.2\)") +install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.3\)") +install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.4\)") +install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.5.0\)") +install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.5.5\)") +install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.6.0\)") +install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.6.5\)") +install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.7.0\)") +install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.7.5\)") +install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.8.0\)") +install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.9.0\)") +install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.9.1\)") + install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.9.2\)") + install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.10.0\)") + install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.10.1\)") +install(CODE "execute_process\(\ + COMMAND ${CMAKE_COMMAND} -E create_symlink \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart> \ + ${GPGPUSIM_INSTALL_PATH}/$<TARGET_FILE_NAME:cudart>.11.0\)")
\ No newline at end of file diff --git a/Jenkinsfile b/Jenkinsfile index a3db3e5..4ef467b 100644 --- a/Jenkinsfile +++ b/Jenkinsfile @@ -87,23 +87,55 @@ pipeline { ssh [email protected] "cd $PLOTDIR && rm -rf latest && cp -r ${BUILD_NUMBER} latest"' } } + stage('sst-core-build') { + steps { + sh 'rm -rf sstcore-install' + sh 'rm -rf sst-core && git clone [email protected]:sstsimulator/sst-core.git' + sh '''#!/bin/bash + cd sst-core + ./autogen.sh + ./configure --prefix=`realpath ../sstcore-install` --disable-mpi --disable-mem-pools + make -j 10 + make install''' + } + } + stage('sst-elements-build') { + steps { + sh 'rm -rf sstelements-install' + sh 'rm -rf sst-elements && git clone [email protected]:sstsimulator/sst-elements.git' + // First sourcing the env_setup and setup_environment script for env vars + sh '''#!/bin/bash + source ./env-setup/11.0_env_setup.sh + source `pwd`/setup_environment + cd sst-elements + ./autogen.sh + ./configure --prefix=`realpath ../sstelements-install` --with-sst-core=`realpath ../sstcore-install` --with-cuda=$CUDA_INSTALL_PATH --with-gpgpusim=$GPGPUSIM_ROOT + make -j 10 + make install''' + } + } + stage('sst balar test') { + steps { + sh '''#!/bin/bash + source ./env-setup/11.0_env_setup.sh + source `pwd`/setup_environment sst + ./sstcore-install/bin/sst-test-elements -p ./sst-elements/src/sst/elements/balar/tests''' + } + } } post { success { -// sh 'git remote rm upstream' - emailext body:'''${SCRIPT, template="groovy-html.success.template"}''', + emailext body: "See ${BUILD_URL}.", recipientProviders: [[$class: 'CulpritsRecipientProvider'], [$class: 'RequesterRecipientProvider']], - subject: "[AALP Jenkins] Build #${BUILD_NUMBER} - Success!", - attachmentsPattern: 'correl.*.txt', + subject: "[AALP Jenkins] Build ${JOB_NAME} #${BUILD_NUMBER} - Success!", to: '[email protected]' } failure { -// sh 'git remote rm upstream' emailext body: "See ${BUILD_URL}", recipientProviders: [[$class: 'CulpritsRecipientProvider'], [$class: 'RequesterRecipientProvider']], - subject: "[AALP Jenkins] Build #${BUILD_NUMBER} - ${currentBuild.result}", + subject: "[AALP Jenkins] Build ${JOB_NAME} #${BUILD_NUMBER} - ${currentBuild.result}", to: '[email protected]' } } @@ -34,6 +34,7 @@ INTERSIM ?= intersim2 include version_detection.mk +# Check for debug ifeq ($(GPGPUSIM_CONFIG), gcc-$(CC_VERSION)/cuda-$(CUDART_VERSION)/debug) export DEBUG=1 else @@ -168,6 +169,7 @@ $(SIM_LIB_DIR)/libcudart.so: makedirs $(LIBS) cudalib if [ ! -f $(SIM_LIB_DIR)/libcudart.so.10.0 ]; then ln -s libcudart.so $(SIM_LIB_DIR)/libcudart.so.10.0; fi if [ ! -f $(SIM_LIB_DIR)/libcudart.so.10.1 ]; then ln -s libcudart.so $(SIM_LIB_DIR)/libcudart.so.10.1; fi if [ ! -f $(SIM_LIB_DIR)/libcudart.so.11.0 ]; then ln -s libcudart.so $(SIM_LIB_DIR)/libcudart.so.11.0; fi + if [ ! -f $(SIM_LIB_DIR)/libcudart_mod.so ]; then ln -s libcudart.so $(SIM_LIB_DIR)/libcudart_mod.so; fi $(SIM_LIB_DIR)/libcudart.dylib: makedirs $(LIBS) cudalib g++ -dynamiclib -Wl,-headerpad_max_install_names,-undefined,dynamic_lookup,-compatibility_version,1.1,-current_version,1.1\ @@ -266,7 +266,7 @@ To run Pytorch applications with the simulator, install the modified Pytorch lib ## Step 3: Run -Before we run, we need to make sure the application's executable file is dynamically linked to CUDA runtime library. This can be done during compilation of your program by introducing the nvcc flag "--cudart shared" in makefile (quotes should be excluded). +Before we run, we need to make sure the application's executable file is dynamically linked to CUDA runtime library. This can be done during compilation of your program by introducing the nvcc flag "-lcudart" in makefile (quotes should be excluded). To confirm the same, type the follwoing command: diff --git a/aerialvision/configs.py b/aerialvision/configs.py index f0389ac..01dba2e 100644 --- a/aerialvision/configs.py +++ b/aerialvision/configs.py @@ -61,7 +61,7 @@ # Vancouver, BC V6T 1Z4 -import ConfigParser, os +import configparser, os userSettingPath = os.path.join(os.environ['HOME'], '.gpgpu_sim', 'aerialvision') @@ -69,14 +69,14 @@ userSettingPath = os.path.join(os.environ['HOME'], '.gpgpu_sim', 'aerialvision') class AerialVisionConfig: def __init__(self): - self.config = ConfigParser.SafeConfigParser() + self.config = configparser.SafeConfigParser() self.config.read( os.path.join(userSettingPath, 'config.rc') ) def print_all(self): for section in self.config.sections(): for option in self.config.options(section): value = self.config.get(section, option) - print "\t%s.%s = %s" % (section, option, value); + print("\t%s.%s = %s" % (section, option, value)); def get_value(self, section, option, default): if (self.config.has_option(section, option)): @@ -90,10 +90,11 @@ avconfig = AerialVisionConfig() #Unit test / configviewer def main(): - print "AerialVision Options:" + print("AerialVision Options:") avconfig.print_all() - print ""; + print(""); if __name__ == "__main__": main() + diff --git a/aerialvision/guiclasses.py b/aerialvision/guiclasses.py index 04036a8..f4ecd29 100644 --- a/aerialvision/guiclasses.py +++ b/aerialvision/guiclasses.py @@ -64,10 +64,10 @@ import time import os import array -import Tkinter as Tk +import tkinter as Tk import matplotlib matplotlib.use('TkAgg') -from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk from matplotlib.figure import Figure import matplotlib as mpl from matplotlib.colors import colorConverter @@ -250,19 +250,19 @@ class formEntry: self.cXAxisData.delete(0, Tk.END) self.cYAxisData.delete(0, Tk.END) - + #filling in xAxis vars - for keys in self.data[self.fileChosen].keys(): + for keys in list(self.data[self.fileChosen].keys()): if keys == 'globalCycle': self.cXAxisData.insert(Tk.END, keys) #filling in yAxis vars #Need to fill up list alphabetically keysAlpha = [] - for key in self.data[self.fileChosen].keys(): + for key in list(self.data[self.fileChosen].keys()): if key not in ['globalCycle','CFLOG','EXTVARS']:#exclude hacks from list keysAlpha.append(key) - keysAlpha.sort(lambda x, y: cmp(x.lower(),y.lower())) + #keysAlpha.sort(key=lambda x, y: cmp(x.lower(),y.lower())) for keys in keysAlpha: self.cYAxisData.insert(Tk.END, keys) @@ -782,7 +782,7 @@ class graphManager: #self.plot = self.figure.add_subplot(111) self.canvas = FigureCanvasTkAgg(self.figure, master=self.graphArea) self.canvas.get_tk_widget().pack() - self.toolbar = NavigationToolbar2TkAgg(self.canvas, self.toolbarArea) + self.toolbar = NavigationToolbar2Tk(self.canvas, self.toolbarArea) self.toolbar.update() self.plotData() @@ -931,7 +931,7 @@ class graphManager: - if self.simplerName.has_key('globalTotInsn') == 'False': + if ('globalTotInsn' in self.simplerName) == 'False': graphOption = 1 if (graphOption == 1): @@ -972,7 +972,7 @@ class graphManager: graphOption = "NULL" - if self.simplerName.has_key('globalTotInsn') == 'False': + if ('globalTotInsn' in self.simplerName) == 'False': graphOption = 1 if (graphOption == 1): @@ -1018,7 +1018,7 @@ class graphManager: #if there are kernals.. we need to adjust the x axis for proper labelling #Need to make changes here.. works for now though - if self.simplerName.has_key('globalTotInsn'): + if 'globalTotInsn' in self.simplerName: x = self.updateVarKernal(x) concentrationFactor = len(x) // 512 + 1 @@ -1038,7 +1038,7 @@ class graphManager: yoff = numpy.array([0.0] * numCols) #variable use to remember the last top location of a bar so that we may stack the proceeding bar on top of it #Legendname = ['UNUSED', 'UNUSED', 'FQPUSHED','ICNT_PUSHED','ICNT_INJECTED','ICNT_AT_DEST','DRAMQ','DRAM_PROCESSING_START','DRAM_PROCESSING_END','DRAM_OUTQ','2SH_ICNT_PUSHED','2SH_ICNT_INJECTED','2SH_ICNT_AT_DEST','2SH_FQ_POP','RETURN_Q']; Legendname = ['N/A', 'N/A','N/A','IcntInpBuf','N/A','Icnt2DRAM','N/A','N/A','N/A','DRAM','2Sh_IcntInpBuf','N/A','Icnt2shd','N/A','N/A']; - BarSequence = range(numRows-1,-1,-1) + BarSequence = list(range(numRows-1,-1,-1)) if yAxis == 'WarpDivergenceBreakdown': Legendname = [] @@ -1046,21 +1046,21 @@ class graphManager: Legendname.append('Data Hazard') Legendname.append('Stall') for c in range(2, numRows): - Legendname.append('W' + `4*(c-2)+1` + ':' + `4*(c-1)`) - BarSequence = range(0,numRows) + Legendname.append('W' + repr(4*(c-2)+1) + ':' + repr(4*(c-1))) + BarSequence = list(range(0,numRows)) if yAxis == 'WarpIssueSlotBreakdown': Legendname = [] for c in range(0, numRows): - Legendname.append('W' + `c`) - BarSequence = range(0,numRows) + Legendname.append('W' + repr(c)) + BarSequence = list(range(0,numRows)) dynamic_warp_resolution = 32 if yAxis == 'WarpIssueDynamicIdBreakdown': Legendname = [] for c in range(0, numRows): - Legendname.append('W' + `dynamic_warp_resolution*c` + ":" + `dynamic_warp_resolution*(c+1)`) - BarSequence = range(0,numRows) + Legendname.append('W' + repr(dynamic_warp_resolution*c) + ":" + repr(dynamic_warp_resolution*(c+1))) + BarSequence = list(range(0,numRows)) yoff_max = numpy.array([0.0] * numCols) for row in range(numRows-1,-1,-1): @@ -1102,10 +1102,10 @@ class graphManager: for label in self.plot.get_yticklabels(): label.set_fontsize(plotFormat.yticksFontSize) - self.canvas.show() + self.canvas.draw() def type4Variable(self, x, xAxis, y, yAxis, plotID): - keys = y.keys() + keys = list(y.keys()) keys.sort() if (self.dataPointer.graphChosen == self.possGraphs[3]): @@ -1251,7 +1251,7 @@ class graphManager: self.plot.set_title(self.plotFormatInfo[self.currPlot].title) self.plot.set_xlabel(self.plotFormatInfo[self.currPlot].xlabel, fontsize = self.plotFormatInfo[self.currPlot].labelFontSize) self.plot.set_ylabel(self.plotFormatInfo[self.currPlot].ylabel, fontsize = self.plotFormatInfo[self.currPlot].labelFontSize) - self.canvas.show() + self.canvas.draw() def plotMultVarLine(self, x, xAxis, y, yAxis): @@ -1261,7 +1261,7 @@ class graphManager: self.plotFormatInfo[self.currPlot].InitLabels(xlabel = xAxis, ylabel = yAxis, cbarlabel = '', title = '') self.plot.set_xlabel(self.plotFormatInfo[self.currPlot].xlabel, fontsize = self.plotFormatInfo[self.currPlot].labelFontSize) self.plot.set_ylabel(self.plotFormatInfo[self.currPlot].ylabel, fontsize = self.plotFormatInfo[self.currPlot].labelFontSize) - self.canvas.show() + self.canvas.draw() def plotScatter(self, x, xAxis, y, yAxis, plotID): @@ -1275,7 +1275,7 @@ class graphManager: self.plot.set_title(plotFormat.title, fontsize = plotFormat.labelFontSize) self.plot.set_xlabel(plotFormat.xlabel, fontsize = plotFormat.labelFontSize) self.plot.set_ylabel(plotFormat.ylabel, fontsize = plotFormat.labelFontSize) - self.canvas.show() + self.canvas.draw() def takeDerivativeMult(self,x,y): @@ -1347,12 +1347,12 @@ class graphManager: # put number on axis if there are more than one ticks if (self.xAxisStepsWilStack[self.currPlot] != 1): - for count in range(0,len(x),len(x)/self.xAxisStepsWilStack[self.currPlot]): + for count in range(0,len(x),int(len(x)/self.xAxisStepsWilStack[self.currPlot])): xlabelValues.append(x[count]) xlabelPos.append(xticksPos[count]) - print self.yAxisStepsWilStack[self.currPlot] - for count in range(0,len(y),len(y)/self.yAxisStepsWilStack[self.currPlot]): + print(self.yAxisStepsWilStack[self.currPlot]) + for count in range(0,len(y),int(len(y)/self.yAxisStepsWilStack[self.currPlot])): ylabelValues.append(yTicks[count]) ylabelPos.append(yticksPos[count]) @@ -1387,7 +1387,7 @@ class graphManager: xtickStep = x[1] - x[0] self.plot.set_xlim(0 / xtickStep - 0.5, self.xlim / xtickStep + 0.5) - self.canvas.show() + self.canvas.draw() def updateWilTicks(self, z): x= [] @@ -1480,7 +1480,7 @@ class graphManager: else: for iter in range(0, self.dataPointer.dydx): if self.simplerName[self.dataPointer.dataChosenY].type == 4: - keys = self.simplerName[self.dataPointer.dataChosenY].data.keys() + keys = list(self.simplerName[self.dataPointer.dataChosenY].data.keys()) keys.sort() y = [] for iter in keys: @@ -1523,7 +1523,7 @@ class graphManager: entry[self.currPlot] = (maxEntry, minEntry) cmap = self.plotFormatInfo[self.currPlot].cmap - plotCMap = apply(Tk.OptionMenu, (root[-1], cmap) + tuple(PlotFormatInfo.cmapOptions)) + plotCMap = Tk.OptionMenu(*(root[-1], cmap) + tuple(PlotFormatInfo.cmapOptions)) plotCMap.pack(side = Tk.LEFT, padx = 5) @@ -1612,7 +1612,7 @@ class graphManager: for self.currPlot in range(1,numPlots + 1): self.findKernalLocs() - if vars.has_key(str(self.currPlot)): + if str(self.currPlot) in vars: if vars[str(self.currPlot)].get() == 1: self.dataPointer.dydx += 1 @@ -1681,12 +1681,12 @@ class graphManager: if (self.yAxisStepsWilStack[plotToIncrease] == 1): self.yAxisStepsWilStack[plotToIncrease] = 2 self.yAxisStepsWilStack[plotToIncrease] = int(float(self.yAxisStepsWilStack[plotToIncrease])*1.50) - print self.yAxisStepsWilStack[plotToIncrease] + print(self.yAxisStepsWilStack[plotToIncrease]) self.plotDataForNewBinning(plotToIncrease) def collectDataDecreaseYBinning(self, currPlot, remove = False): plotToDecrease = int(currPlot[0]) - print self.yAxisStepsWilStack[plotToDecrease] + print(self.yAxisStepsWilStack[plotToDecrease]) if (remove == True): self.yAxisStepsWilStack[plotToDecrease] = 1 else: @@ -1751,7 +1751,7 @@ class graphManager: entries[self.currPlot].append(Tk.Entry(root, width = 50)) entries[self.currPlot][-1].grid(row = currentRow, column = 4, padx = 10) entries[self.currPlot][-1].insert(0, self.plot.get_xlabel()) - if self.colorbars.has_key(self.currPlot): + if self.currPlot in self.colorbars: plotLabel3 = Tk.Label(root, text = 'Colorbar: ', bg = 'white') plotLabel3.grid(row = currentRow, column = 5) entries[self.currPlot].append(Tk.Entry(root, width = 20)) @@ -1821,7 +1821,7 @@ class graphManager: self.plot.set_ylabel(plotFormat.ylabel, fontsize=plotFormat.labelFontSize) plotFormat.xlabel = entries[self.currPlot][1].get() self.plot.set_xlabel(plotFormat.xlabel, fontsize=plotFormat.labelFontSize) - if self.colorbars.has_key(self.currPlot): + if self.currPlot in self.colorbars: plotFormat.cbarlabel = entries[self.currPlot][2].get() self.colorbars[self.currPlot].set_label(plotFormat.cbarlabel, fontsize=plotFormat.labelFontSize) else: @@ -1841,7 +1841,7 @@ class graphManager: ytickslabels[n].set_fontsize(plotFormat.yticksFontSize) # change colorbar ticks label fontsize - if self.colorbars.has_key(self.currPlot): + if self.currPlot in self.colorbars: for label in self.colorbars[self.currPlot].ax.get_yticklabels(): label.set_fontsize(plotFormat.cticksFontSize) @@ -1851,7 +1851,7 @@ class graphManager: master.destroy() ## Now replot with changes..... - self.canvas.show() + self.canvas.draw() def zoomButton(self): #Variable initializations @@ -1980,7 +1980,7 @@ class graphManager: plot.set_xticks(xlabelPos) master.destroy() - self.canvas.show() + self.canvas.draw() class NaviPlotInfo: @@ -2224,6 +2224,7 @@ class newTextTab: countLines = 1 for lines in self.file.readlines(): + lines = lines.decode() self.textbox.insert(Tk.END, str(countLines) + '. ' + lines, ('normal')) countLines += 1 countLines -= 1 @@ -2232,7 +2233,7 @@ class newTextTab: figure = Figure(figsize=(22,5), dpi = 70) self.histArea = FigureCanvasTkAgg(figure, master= bottomFrame) self.histArea.get_tk_widget().pack() - toolbar = NavigationToolbar2TkAgg(self.histArea, toolbarFrame) + toolbar = NavigationToolbar2Tk(self.histArea, toolbarFrame) toolbar.update() self.histogram = figure.add_subplot(111) cid = figure.canvas.mpl_connect('button_press_event',self.onclick) @@ -2285,8 +2286,8 @@ class newTextTab: count += 1 def yview(self, *args): - apply(self.textbox.yview, args) - apply(self.statstextbox.yview, args) + self.textbox.yview(*args) + self.statstextbox.yview(*args) def onclick(self, event): if event.button == 3: @@ -2298,6 +2299,7 @@ class newTextTab: self.textbox.delete(0.0, Tk.END) self.file = open(self.fileChosen, 'r') for lines in self.file.readlines(): + lines=lines.decode() if (countLines < event.xdata - 1) or (countLines > event.xdata + 1): self.textbox.insert(Tk.END, str(countLines) + '. ' + lines, ('normal')) else: @@ -2317,8 +2319,8 @@ class newTextTab: - apply(self.textbox.yview, args) - apply(self.statstextbox.yview, args) + self.textbox.yview(*args) + self.statstextbox.yview(*args) def chooseFileCuda(self, *event): self.fileChosen = self.cAvailableCudaFiles.get('active') @@ -2572,3 +2574,4 @@ class newTextTab: + diff --git a/aerialvision/lexyacc.py b/aerialvision/lexyacc.py index d657383..53541ed 100644 --- a/aerialvision/lexyacc.py +++ b/aerialvision/lexyacc.py @@ -82,7 +82,7 @@ def import_user_defined_variables(variables): try: file = open(os.path.join(userSettingPath, 'variables.txt'),'r') except: - print "No variables.txt file found." + print("No variables.txt file found.") return #this can be replaced with a proper lex-yacc parser later @@ -96,7 +96,7 @@ def import_user_defined_variables(variables): continue # parse the line containing definition of a stat variable - s = line.split(",") + s = line.split(',') statName = s[0] statVar = vc.variable('', 1, 0) statVar.importFromString(line) @@ -104,8 +104,9 @@ def import_user_defined_variables(variables): # add parsed stat variable to the searchable map variables[statName] = statVar - except Exception, (e): - print "error:",e,", in variables.txt line:",line + except Exception as xxx_todo_changeme: + (e) = xxx_todo_changeme + print("error:",e,", in variables.txt line:",line) # Parses through a given log file for data def parseMe(filename): @@ -136,7 +137,7 @@ def parseMe(filename): t.lexer.lineno += t.value.count("\n") def t_error(t): - print "Illegal character '%s'" % t.value[0] + print("Illegal character '%s'" % t.value[0]) t.lexer.skip(1) lex.lex() @@ -202,14 +203,14 @@ def parseMe(filename): # generate a lookup table based on the specified name in log file for each stat stat_lookuptable = {} - for name, var in variables.iteritems(): + for name, var in variables.items(): if (name == 'CFLOG'): continue; if (var.lookup_tag != ''): stat_lookuptable[var.lookup_tag] = var else: stat_lookuptable[name.lower()] = var - + inputData = 'NULL' # a table containing all the metrics that has received the missing data warning @@ -218,19 +219,19 @@ def parseMe(filename): def p_sentence(p): '''sentence : WORD NUMBERSEQUENCE''' #print p[0], p[1],p[2] - num = p[2].split(" ") + num = p[2].split(' ') # detect empty data entry for particular metric and print a warning if p[2] == '': if not p[1] in stat_missing_warned: - print "WARNING: Sample entry for metric '%s' has no data. Skipping..." % p[1] + print("WARNING: Sample entry for metric '%s' has no data. Skipping..." % p[1]) stat_missing_warned[p[1]] = True return lookup_input = p[1].lower() if (lookup_input in stat_lookuptable): if (lookup_input == "globalcyclecount") and (int(num[0]) % 10000 == 0): - print "Processing global cycle %s" % num[0] + print("Processing global cycle %s" % num[0]) stat = stat_lookuptable[lookup_input] if (stat.type == 1): @@ -294,7 +295,7 @@ def parseMe(filename): def p_error(p): if p: - print("Syntax error at '%s'" % p.value) + print(("Syntax error at '%s'" % p.value)) else: print("Syntax error at EOF") @@ -306,11 +307,12 @@ def parseMe(filename): else: file = open(filename, 'r') while file: - line = file.readline() + line = file.readline().decode() + if not line : break - nameNdata = line.split(":") + nameNdata = line.split(':') if (len(nameNdata) != 2): - print("Syntax error at '%s'" % line) + print(("Syntax error at '%s'" % line)) namePart = nameNdata[0].strip() dataPart= nameNdata[1].strip() parts = [' ', namePart, dataPart] @@ -323,3 +325,4 @@ def parseMe(filename): + diff --git a/aerialvision/lexyaccbookmark.py b/aerialvision/lexyaccbookmark.py index 42c6b40..7aa2f80 100644 --- a/aerialvision/lexyaccbookmark.py +++ b/aerialvision/lexyaccbookmark.py @@ -108,7 +108,7 @@ def parseMe(): def t_error(t): - print "Illegal character '%s'" % t.value[0] + print("Illegal character '%s'" % t.value[0]) t.lexer.skip(1) lex.lex() @@ -150,7 +150,7 @@ def parseMe(): pass else: - print 'An Parsing Error has occurred' + print('An Parsing Error has occurred') @@ -159,7 +159,7 @@ def parseMe(): def p_error(p): if p: - print("Syntax error at '%s'" % p.value) + print(("Syntax error at '%s'" % p.value)) else: print("Syntax error at EOF") @@ -168,7 +168,7 @@ def parseMe(): try: file = open(os.environ['HOME'] + '/.gpgpu_sim/aerialvision/bookmarks.txt', 'r') inputData = file.readlines() - except IOError,e: + except IOError as e: if e.errno == 2: inputData = '' else: @@ -178,3 +178,4 @@ def parseMe(): yacc.parse(x[0:-1]) # ,debug=True) return listBookmarks + diff --git a/aerialvision/lexyacctexteditor.py b/aerialvision/lexyacctexteditor.py index 51d3ced..57b41db 100644 --- a/aerialvision/lexyacctexteditor.py +++ b/aerialvision/lexyacctexteditor.py @@ -88,7 +88,7 @@ def textEditorParseMe(filename): t.lexer.lineno += t.value.count("\n") def t_error(t): - print "Illegal character '%s'" % t.value[0] + print("Illegal character '%s'" % t.value[0]) t.lexer.skip(1) lex.lex() @@ -109,8 +109,8 @@ def textEditorParseMe(filename): def p_error(p): if p: - print("Syntax error at '%s'" % p.value) - print p + print(("Syntax error at '%s'" % p.value)) + print(p) else: print("Syntax error at EOF") @@ -152,17 +152,18 @@ def ptxToCudaMapping(filename): loc = int(m.group(2)) count += 1 - x = map.keys() + x = list(map.keys()) return map #Unit test / playground def main(): data = textEditorParseMe(sys.argv[1]) - print data[100] + print(data[100]) if __name__ == "__main__": main() + diff --git a/aerialvision/organizedata.py b/aerialvision/organizedata.py index 090b90f..f5d5312 100644 --- a/aerialvision/organizedata.py +++ b/aerialvision/organizedata.py @@ -99,7 +99,7 @@ def organizedata(fileVars): } data_type_char = {int:'I', float:'f'} - print "Organizing data into internal format..." + print("Organizing data into internal format...") # Organize globalCycle in advance because it is used as a reference if ('globalCycle' in fileVars): @@ -107,28 +107,28 @@ def organizedata(fileVars): fileVars['globalCycle'].data = organizeFunction[statData.organize](statData.data, data_type_char[statData.datatype]) # Organize other stat data into internal format - for statName, statData in fileVars.iteritems(): + for statName, statData in fileVars.items(): if (statName != 'CFLOG' and statName != 'globalCycle' and statData.organize != 'custom'): fileVars[statName].data = organizeFunction[statData.organize](statData.data, data_type_char[statData.datatype]) # Custom routines to organize stat data into internal format - if fileVars.has_key('averagemflatency'): + if 'averagemflatency' in fileVars: zeros = [] for count in range(len(fileVars['averagemflatency'].data),len(fileVars['globalCycle'].data)): zeros.append(0) fileVars['averagemflatency'].data = zeros + fileVars['averagemflatency'].data - if (skipCFLog == 0) and fileVars.has_key('CFLOG'): + if (skipCFLog == 0) and 'CFLOG' in fileVars: ptxFile = CFLOGptxFile statFile = CFLOGInsnInfoFile - print "PC Histogram to CUDA Src = %d" % convertCFLog2CUDAsrc + print("PC Histogram to CUDA Src = %d" % convertCFLog2CUDAsrc) parseCFLOGCUDA = convertCFLog2CUDAsrc if parseCFLOGCUDA == 1: - print "Obtaining PTX-to-CUDA Mapping from %s..." % ptxFile + print("Obtaining PTX-to-CUDA Mapping from %s..." % ptxFile) map = lexyacctexteditor.ptxToCudaMapping(ptxFile.rstrip()) - print "Obtaining Program Range from %s..." % statFile + print("Obtaining Program Range from %s..." % statFile) maxStats = max(lexyacctexteditor.textEditorParseMe(statFile.rstrip()).keys()) if parseCFLOGCUDA == 1: @@ -136,7 +136,7 @@ def organizedata(fileVars): for lines in map: for ptxLines in map[lines]: newMap[ptxLines] = lines - print " Total number of CUDA src lines = %s..." % len(newMap) + print(" Total number of CUDA src lines = %s..." % len(newMap)) markForDel = [] for ptxLines in newMap: @@ -144,7 +144,7 @@ def organizedata(fileVars): markForDel.append(ptxLines) for lines in markForDel: del newMap[lines] - print " Number of touched CUDA src lines = %s..." % len(newMap) + print(" Number of touched CUDA src lines = %s..." % len(newMap)) fileVars['CFLOGglobalPTX'] = vc.variable('',2,0) fileVars['CFLOGglobalCUDA'] = vc.variable('',2,0) @@ -152,7 +152,7 @@ def organizedata(fileVars): count = 0 for iter in fileVars['CFLOG']: - print "Organizing data for %s" % iter + print("Organizing data for %s" % iter) fileVars[iter + 'PTX'] = fileVars['CFLOG'][iter] fileVars[iter + 'PTX'].data = CFLOGOrganizePTX(fileVars['CFLOG'][iter].data, fileVars['CFLOG'][iter].maxPC) @@ -174,7 +174,7 @@ def organizedata(fileVars): for columns in range(0, len(fileVars[iter + 'CUDA'].data[rows])): fileVars['CFLOGglobalCUDA'].data[rows][columns] += fileVars[iter + 'CUDA'].data[rows][columns] except: - print "Error in generating globalCFLog data" + print("Error in generating globalCFLog data") count += 1 del fileVars['CFLOG'] @@ -231,10 +231,10 @@ def nullOrganizedStackedBar(nullVar, datatype_c): for row in range (0,len(organized)): newy = array.array(datatype_c, [0 for col in range(newLen)]) for col in range(0, len(organized[row])): - newcol = col / n_data + newcol = int(col / n_data) newy[newcol] += organized[row][col] for col in range(0, len(newy)): - newy[col] /= n_data + newy[col] = int(newy[col]/n_data) organized[row] = newy return organized @@ -320,15 +320,15 @@ def CFLOGOrganizeCuda(list, ptx2cudamap): nSamples = len(list[0]) # create a dictionary of empty data array (one array per cuda source line) - for ptxline, cudaline in ptx2cudamap.iteritems(): - if tmp.has_key(cudaline): + for ptxline, cudaline in ptx2cudamap.items(): + if cudaline in tmp: pass else: tmp[cudaline] = [0 for lengthData in range(nSamples)] for cudaline in tmp: - for ptxLines, mapped_cudaline in ptx2cudamap.iteritems(): + for ptxLines, mapped_cudaline in ptx2cudamap.items(): if mapped_cudaline == cudaline: for lengthData in range(nSamples): tmp[cudaline][lengthData] += list[ptxLines][lengthData] @@ -336,7 +336,7 @@ def CFLOGOrganizeCuda(list, ptx2cudamap): final = [] for iter in range(min(tmp.keys()),max(tmp.keys())): - if tmp.has_key(iter): + if iter in tmp: final.append(tmp[iter]) else: final.append([0 for lengthData in range(nSamples)]) @@ -356,3 +356,4 @@ def CFLOGOrganizeCuda(list, ptx2cudamap): # return organized + diff --git a/aerialvision/parser.out b/aerialvision/parser.out new file mode 100644 index 0000000..809874f --- /dev/null +++ b/aerialvision/parser.out @@ -0,0 +1,47 @@ +Created by PLY version 3.11 (http://www.dabeaz.com/ply) + +Grammar + +Rule 0 S' -> sentence +Rule 1 sentence -> WORD NUMBERSEQUENCE + +Terminals, with rules where they appear + +NUMBERSEQUENCE : 1 +WORD : 1 +error : + +Nonterminals, with rules where they appear + +sentence : 0 + +Parsing method: LALR + +state 0 + + (0) S' -> . sentence + (1) sentence -> . WORD NUMBERSEQUENCE + + WORD shift and go to state 2 + + sentence shift and go to state 1 + +state 1 + + (0) S' -> sentence . + + + +state 2 + + (1) sentence -> WORD . NUMBERSEQUENCE + + NUMBERSEQUENCE shift and go to state 3 + + +state 3 + + (1) sentence -> WORD NUMBERSEQUENCE . + + $end reduce using rule 1 (sentence -> WORD NUMBERSEQUENCE .) + diff --git a/aerialvision/parsetab.py b/aerialvision/parsetab.py new file mode 100644 index 0000000..47a3884 --- /dev/null +++ b/aerialvision/parsetab.py @@ -0,0 +1,31 @@ + +# parsetab.py +# This file is automatically generated. Do not edit. +# pylint: disable=W,C,R +_tabversion = '3.10' + +_lr_method = 'LALR' + +_lr_signature = 'NUMBERSEQUENCE WORDsentence : WORD NUMBERSEQUENCE' + +_lr_action_items = {'WORD':([0,],[2,]),'$end':([1,3,],[0,-1,]),'NUMBERSEQUENCE':([2,],[3,]),} + +_lr_action = {} +for _k, _v in _lr_action_items.items(): + for _x,_y in zip(_v[0],_v[1]): + if not _x in _lr_action: _lr_action[_x] = {} + _lr_action[_x][_k] = _y +del _lr_action_items + +_lr_goto_items = {'sentence':([0,],[1,]),} + +_lr_goto = {} +for _k, _v in _lr_goto_items.items(): + for _x, _y in zip(_v[0], _v[1]): + if not _x in _lr_goto: _lr_goto[_x] = {} + _lr_goto[_x][_k] = _y +del _lr_goto_items +_lr_productions = [ + ("S' -> sentence","S'",1,None,None,None), + ('sentence -> WORD NUMBERSEQUENCE','sentence',2,'p_sentence','lexyacc.py',220), +] diff --git a/aerialvision/startup.py b/aerialvision/startup.py index ae14fd3..d261c0c 100644 --- a/aerialvision/startup.py +++ b/aerialvision/startup.py @@ -62,11 +62,11 @@ import sys -import Tkinter as Tk +import tkinter as Tk import Pmw import lexyacc import guiclasses -import tkFileDialog as Fd +import tkinter.filedialog as Fd import organizedata import os import os.path @@ -160,7 +160,7 @@ def fileInput(cl_files=None): tmprecentfile = tmprecentfile.split('/') for iter in range(1,len(tmprecentfile) - 1): recentfile = recentfile + '/' + tmprecentfile[iter] - except IOError,e: + except IOError as e: if e.errno == 2: # recentfiles.txt does not exist, ignore and use CWD recentfile = '.' @@ -313,7 +313,7 @@ def loadRecentFile(entry): try: loadfile = open(os.path.join(userSettingPath, 'recentfiles.txt'), 'r') recentfiles = loadfile.readlines() - except IOError,e: + except IOError as e: if e.errno == 2: recentfiles = '' else: @@ -323,7 +323,7 @@ def loadRecentFile(entry): recentFileWindow.pack(side = Tk.TOP) scrollbar = Tk.Scrollbar(recentFileWindow, orient = Tk.VERTICAL) cRecentFile = Tk.Listbox(recentFileWindow, width = 100, height = 15, yscrollcommand = scrollbar.set) - cRecentFile.bind("<Double-Button-1>", lambda(event): recentFileInsert(entry, cRecentFile.get('active'), instance)) + cRecentFile.bind("<Double-Button-1>", lambda event: recentFileInsert(entry, cRecentFile.get('active'), instance)) cRecentFile.pack(side = Tk.LEFT) scrollbar.config(command = cRecentFile.yview) scrollbar.pack(side = Tk.LEFT, fill = Tk.Y) @@ -391,9 +391,9 @@ def addListToListbox(listbox,list): Filenames.append(string) listbox.insert(Tk.END, string) else: - print 'Could not open file: ' + string + print('Could not open file: ' + string) except: - print 'Could not open file: ' + file + print('Could not open file: ' + file) def errorMsg(string): @@ -447,6 +447,7 @@ def submitClicked(instance, num, skipcflog, cflog2cuda, listboxes): startup(res, [TEFiles, TEPTXFiles, TEStatFiles]) def graphAddTab(vars, graphTabs,res, entry): + TabsForGraphs.append(guiclasses.formEntry(graphTabs, str(len(TabsForGraphs) + 1), vars, res, entry)) entry.delete(0, Tk.END) @@ -586,7 +587,7 @@ def startup(res, TEFILES): organizedata.setCFLOGInfoFiles(TEFILES) for files in Filenames: vars[files] = organizedata.organizedata(vars[files]) - + graphAddTab(vars, graphTabs, res, eAddTab) @@ -873,3 +874,4 @@ def manageFilesSubmit(window, listbox): + diff --git a/aerialvision/variableclasses.py b/aerialvision/variableclasses.py index 18850a1..30d8d2d 100644 --- a/aerialvision/variableclasses.py +++ b/aerialvision/variableclasses.py @@ -102,8 +102,9 @@ class variable: assert(self.organize == 'idx2DVec') elif (self.type == 5): assert(self.organize == 'sparse') - except Exception, (e): - print "Error in creating new stat variable from string: %s" % string_spec + except Exception as xxx_todo_changeme: + (e) = xxx_todo_changeme + print("Error in creating new stat variable from string: %s" % string_spec) raise e def initSparseMatrix(self): @@ -133,7 +134,7 @@ def loadLineStatName(filename): global lineStatName file = open(filename, 'r') while file: - line = file.readline() + line = file.readline().decode() if not line : break if (line.startswith('kernel line :')) : line = line.strip() @@ -171,7 +172,7 @@ class cudaLineNo: except: tmp = 0 if cudaLineNo.debug: - print 'Exception in cudaLineNo.takeMax()', self.stats[key] + print('Exception in cudaLineNo.takeMax()', self.stats[key]) return tmp def takeRatioSums(self, key1,key2): @@ -182,9 +183,9 @@ class cudaLineNo: return tmp1/tmp2 except: if cudaLineNo.debug: - print tmp1, tmp2 + print(tmp1, tmp2) if tmp2 == 0 and cudaLineNo.debug: - print 'infinite' + print('infinite') return 0 @@ -209,7 +210,7 @@ class ptxLineNo: return tmp1/tmp2 except: if tmp2 == 0 and ptxLineNo.debug: - print 'infinite' + print('infinite') return 0 @@ -221,3 +222,4 @@ class ptxLineNo: + diff --git a/bin/aerialvision.py b/bin/aerialvision.py index a5b02f0..5cc7ad9 100755 --- a/bin/aerialvision.py +++ b/bin/aerialvision.py @@ -66,20 +66,21 @@ import sys import os if not os.environ['HOME']: - print 'please set your HOME environment variable to your home directory' + print('please set your HOME environment variable to your home directory') sys.exit if not os.environ['GPGPUSIM_ROOT']: - print 'please set your GPGPUSIM_ROOT environment variable to your home directory' + print('please set your GPGPUSIM_ROOT environment variable to your home directory') sys.exit sys.path.append( os.environ['GPGPUSIM_ROOT'] + '/aerialvision/' ) -import Tkinter as Tk +import tkinter as Tk import Pmw import startup import time -from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2TkAgg +from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg, NavigationToolbar2Tk from matplotlib.figure import Figure startup.fileInput(sys.argv[1:]) + diff --git a/configs/tested-cfgs/SM2_GTX480/gpgpusim.config b/configs/tested-cfgs/SM2_GTX480/gpgpusim.config index 609a9ef..bc01821 100644 --- a/configs/tested-cfgs/SM2_GTX480/gpgpusim.config +++ b/configs/tested-cfgs/SM2_GTX480/gpgpusim.config @@ -56,7 +56,7 @@ # In Fermi, the cache and shared memory can be configured to 16kb:48kb(default) or 48kb:16kb -# <nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> +# <sector?>:<nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> # ** Optional parameter - Required when mshr_type==Texture Fifo # Note: Hashing set index function (H) only applies to a set size of 32 or 64. -gpgpu_cache:dl1 N:32:128:4,L:L:m:N:H,S:64:8,8 diff --git a/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config b/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config index c83159f..ef47ddf 100644 --- a/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config +++ b/configs/tested-cfgs/SM3_KEPLER_TITAN/gpgpusim.config @@ -99,7 +99,7 @@ # Greedy then oldest scheduler -gpgpu_scheduler gto -# <nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> +# <sector?>:<nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> # ** Optional parameter - Required when mshr_type==Texture Fifo # Note: Hashing set index function (H) only applies to a set size of 32 or 64. # The defulat is to disable the L1 cache, unless cache modifieres are used diff --git a/configs/tested-cfgs/SM6_TITANX/gpgpusim.config b/configs/tested-cfgs/SM6_TITANX/gpgpusim.config index 652f0a0..7d3e2d4 100644 --- a/configs/tested-cfgs/SM6_TITANX/gpgpusim.config +++ b/configs/tested-cfgs/SM6_TITANX/gpgpusim.config @@ -123,7 +123,7 @@ -gpgpu_dual_issue_diff_exec_units 1 ## L1/shared memory configuration -# <nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> +# <sector?>:<nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> # ** Optional parameter - Required when mshr_type==Texture Fifo # Note: Hashing set index function (H) only applies to a set size of 32 or 64. # The defulat is to disable the L1 cache, unless cache modifieres are used diff --git a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config index 2a9bff0..6ff4b6c 100644 --- a/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config +++ b/configs/tested-cfgs/SM75_RTX2060/gpgpusim.config @@ -10,6 +10,7 @@ -gpgpu_runtime_pending_launch_count_limit 2048 -gpgpu_kernel_launch_latency 5000 -gpgpu_TB_launch_latency 0 +-gpgpu_max_concurrent_kernel 128 # Compute Capability -gpgpu_compute_capability_major 7 @@ -82,7 +83,7 @@ -gpgpu_dual_issue_diff_exec_units 1 ## L1/shared memory configuration -# <nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> +# <sector?>:<nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> # ** Optional parameter - Required when mshr_type==Texture Fifo # In adaptive cache, we adaptively assign the remaining shared memory to L1 cache # For more info, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x diff --git a/configs/tested-cfgs/SM75_RTX2060_S/gpgpusim.config b/configs/tested-cfgs/SM75_RTX2060_S/gpgpusim.config index 0fb4742..08ac752 100644 --- a/configs/tested-cfgs/SM75_RTX2060_S/gpgpusim.config +++ b/configs/tested-cfgs/SM75_RTX2060_S/gpgpusim.config @@ -43,6 +43,7 @@ -gpgpu_runtime_sync_depth_limit 2 -gpgpu_runtime_pending_launch_count_limit 2048 -gpgpu_kernel_launch_latency 5000 +-gpgpu_max_concurrent_kernel 128 # Compute Capability -gpgpu_compute_capability_major 7 @@ -127,7 +128,7 @@ -gpgpu_num_reg_banks 16 -gpgpu_reg_file_port_throughput 2 -# <nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> +# <sector?>:<nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> # ** Optional parameter - Required when mshr_type==Texture Fifo -gpgpu_adaptive_cache_config 0 -gpgpu_l1_banks 4 diff --git a/configs/tested-cfgs/SM7_GV100/accelwattch_ptx_sim.xml b/configs/tested-cfgs/SM7_GV100/accelwattch_ptx_sim.xml new file mode 100644 index 0000000..d94d5bd --- /dev/null +++ b/configs/tested-cfgs/SM7_GV100/accelwattch_ptx_sim.xml @@ -0,0 +1,623 @@ +<?xml version="1.0" ?>
+<component id="root" name="root">
+ <component id="system" name="system">
+<!-- Copyright (c) 2018-2021, Vijay Kandiah, Junrui Pan, Mahmoud Khairy, Scott Peverelle, Timothy Rogers, Tor M. Aamodt, Nikos Hardavellas
+Northwestern University, Purdue University, The University of British Columbia
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer;
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution;
+3. Neither the names of Northwestern University, Purdue University,
+ The University of British Columbia nor the names of their contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE. -->
+
+ <!-- DYNAMIC Power Activity Factors -->
+
+ <param name="TOT_INST" value="2" /> <!--Instruction Buffer Activity Factor(Total Warp Instructions)-->
+ <param name="FP_INT" value="4.57" /> <!--Scheduler Activity Factor(Non-Memory Warp Instructons)-->
+ <param name="IC_H" value="11.44089762" /> <!--Instruction Cache Hits -->
+ <param name="IC_M" value="21.76302498" /> <!--Instruction Cache Misses-->
+ <param name="DC_RH" value="7.737353491" /> <!--L1 Data Cache Read Hits-->
+ <param name="DC_RM" value="8.618027871" /> <!--L1 Data Cache Read Misses-->
+ <param name="DC_WH" value="0.53469516" /> <!--L1 Data Cache Write Hits-->
+ <param name="DC_WM" value="13.9055689" /> <!--L1 Data Cache Write Misses-->
+ <param name="CC_H" value="0.65916315" /> <!--Constant Cache Hits-->
+ <param name="CC_M" value="0.73418985" /> <!--Constant Cache Misses-->
+ <param name="SHRD_ACC" value="1.313660815" /> <!--Shared Memory Accesses-->
+ <param name="REG_RD" value="0.053279375" /> <!--Register Reads-->
+ <param name="REG_WR" value="0.079919063" /> <!--Register Writes-->
+ <param name="INT_ACC" value="3.429666768" /> <!--Integer ALU Accesses-->
+ <param name="FP_ACC" value="0.711591276" /> <!--FPU Accesses-->
+ <param name="DP_ACC" value="0.742812382" /> <!--Integer Accesses-->
+ <param name="INT_MUL_ACC" value="0.148636575" /> <!--Integer MUL Accesses-->
+ <param name="FP_MUL_ACC" value="0.212559571" /> <!--FP MUL Accesses-->
+ <param name="FP_SQRT_ACC" value="1.241271438" /> <!--SFU: sqrt Accesses-->
+ <param name="FP_LG_ACC" value="0.59034036" /> <!--SFU: log Accesses-->
+ <param name="FP_SIN_ACC" value="0.212555149" /> <!--SFU: sin/cos Accesses-->
+ <param name="FP_EXP_ACC" value="0.702043615" /> <!--SFU: exponent Accesses-->
+ <param name="DP_MUL_ACC" value="0.282564496" /> <!--DP MUL Accesses-->
+ <param name="TENSOR_ACC" value="2.485" /> <!--Tensor Accesses-->
+ <param name="TEX_ACC" value="0.212559047" /> <!--Texture Unit Accesses-->
+ <param name="MEM_RD" value="0.02772" /> <!--DRAM Reads-->
+ <param name="MEM_WR" value="0.0336" /> <!--DRAM Writes-->
+ <param name="MEM_PRE" value="0.00924" /> <!--DRAM Precharge-->
+ <param name="L2_RH" value="1.046834662" /> <!--L2 Data Cache Read Hits-->
+ <param name="L2_RM" value="2.670605032" /> <!--L2 Data Cache Read Misses-->
+ <param name="L2_WH" value="3.269555394" /> <!--L2 Data Cache Write Hits-->
+ <param name="L2_WM" value="2.18020968" /> <!--L2 Data Cache Write Misses-->
+ <param name="NOC_A" value="83.18977901" /> <!--Interconnect Network Accesses-->
+ <param name="PIPE_A" value="0.0257" /> <!--Pipeline Accesses-->
+
+ <!-- PTX Model specific DYNAMIC Power Activity Factors-->
+
+ <param name="TC_H" value="0.01021" /> <!--Texture Cache Hits-->
+ <param name="TC_M" value="0.02466" /> <!--Texture Cache Misses-->
+ <param name="INT_MUL24_ACC" value="0.290770573" /> <!--Integer 24-bit MUL Accesses-->
+ <param name="INT_MUL32_ACC" value="0.252598514" /> <!--Integer 32-bit MUL Accesses-->
+ <param name="INT_DIV_ACC" value="5.121706665" /> <!--Integer DIV Accesses-->
+ <param name="FP_DIV_ACC" value="4.599926258" /> <!--FP DIV Accesses-->
+ <param name="DP_DIV_ACC" value="25.84876211" /> <!--DP DIV Accesses-->
+
+ <!-- STATIC & CONSTANT Power -->
+
+ <param name="constant_power" value="32.32522272" /> <!--Constant power-->
+ <param name="idle_core_power" value="0.28279166"/> <!--Idle SM power-->
+
+ <param name="static_cat1_flane" value="15.29035866"/> <!--INT (ADD+MUL) First Lane Activation Power-->
+ <param name="static_cat1_addlane" value="0.586233603"/> <!--INT (ADD+MUL) Additional Lane Activation Power-->
+
+ <param name="static_cat2_flane" value="18.6179906"/> <!--INT+FP First Lane Activation Power-->
+ <param name="static_cat2_addlane" value="0.645228013"/> <!--INT+FP Additional Lane Activation Power-->
+
+ <param name="static_cat3_flane" value="19.10017723"/> <!--INT+FP+DP First Lane Activation Power-->
+ <param name="static_cat3_addlane" value="0.726863055"/> <!--INT+FP+DP Additional Lane Activation Power-->
+
+ <param name="static_cat4_flane" value="18.55029744"/> <!--INT+FP+SFU First Lane Activation Power-->
+ <param name="static_cat4_addlane" value="0.6099397"/> <!--INT+FP+SFU Additional Lane Activation Power-->
+
+ <param name="static_cat5_flane" value="14.74826681"/> <!--INT+FP+TEX First Lane Activation Power-->
+ <param name="static_cat5_addlane" value="0.514367937"/> <!--INT+FP+TEX Additional Lane Activation Power-->
+
+ <param name="static_cat6_flane" value="48.94875596"/> <!--INT+FP+TENSOR First Lane Activation Power-->
+ <param name="static_cat6_addlane" value="0.0"/> <!--INT+FP+TENSOR Additional Lane Activation Power-->
+
+ <param name="static_light_flane" value="1.965373811"/> <!--LIGHT_SM First Lane Activation Power-->
+ <param name="static_light_addlane" value="0.003966868"/> <!--LIGHT_SM Additional Lane Activation Power-->
+
+ <param name="static_intadd_flane" value="19.70468506"/> <!--INT ADD First Lane Activation Power-->
+ <param name="static_intadd_addlane" value="0.388578623"/> <!--INT ADD Additional Lane Activation Power-->
+
+ <param name="static_intmul_flane" value="16.64811823"/> <!--INT MUL First Lane Activation Power-->
+ <param name="static_intmul_addlane" value="0.281803166"/> <!--INT MUL Additional Lane Activation Power-->
+
+ <param name="static_geomean_flane" value="17.21745077"/> <!--GEOMEAN First Lane Activation Power-->
+ <param name="static_geomean_addlane" value="0.650630555"/> <!--GEOMEAN Additional Lane Activation Power-->
+ <param name="static_shared_flane" value="31.40965691"/> <!--Shared Memory First Lane Activation Power-->
+ <param name="static_l1_flane" value="34.79491352"/> <!--L1D First Lane Activation Power-->
+ <param name="static_l2_flane" value="17.30654755"/> <!--L2D ADD+MUL First Lane Activation Power-->
+
+
+ <!-- LEAVE BELOW UNCHANGED! These are parameters used for initial GPUWattch model left untouched -->
+
+
+ <param name="GPU_Architecture" value="1"/><!-- 0-G80; 1-Fermi; others not supported -->
+ <param name="architecture" value="1"/> <!-- fermi:1 quadro:2 other: undefined-->
+ <param name="number_of_L1Directories" value="0"/>
+ <param name="number_of_L2Directories" value="0"/>
+ <param name="number_of_L2s" value="1"/> <!-- This number means how many L2 clusters in each cluster there can be multiple banks/ports -->
+ <param name="number_of_L3s" value="0"/> <!-- This number means how many L3 clusters -->
+ <param name="number_of_NoCs" value="1"/>
+ <param name="homogeneous_cores" value="1"/><!--1 means homo -->
+ <param name="homogeneous_L2s" value="1"/>
+ <param name="homogeneous_L1Directorys" value="1"/>
+ <param name="homogeneous_L2Directorys" value="1"/>
+ <param name="homogeneous_L3s" value="1"/>
+ <param name="homogeneous_ccs" value="1"/><!--cache coherece hardware -->
+ <param name="homogeneous_NoCs" value="1"/>
+ <param name="core_tech_node" value="23"/><!-- nm -->
+
+ <param name="number_cache_levels" value="2"/>
+ <param name="interconnect_projection_type" value="0"/><!--0: agressive wire technology; 1: conservative wire technology -->
+ <param name="device_type" value="0"/><!--0: HP(High Performance Type); 1: LSTP(Low standby power) 2: LOP (Low Operating Power) -->
+ <param name="longer_channel_device" value="1"/><!-- 0 no use; 1 use when possible -->
+ <param name="machine_bits" value="32"/>
+ <param name="virtual_address_width" value="32"/>
+ <param name="physical_address_width" value="32"/>
+ <param name="virtual_memory_page_size" value="4096"/>
+
+ <param name="IDLE_CORE_N" value="1"/>
+ <stat name="num_idle_cores" value="0"/><!-- Average Number of idle cores during this period -->
+ <stat name="total_cycles" value="total_cycles_match_mcpat"/>
+ <stat name="idle_cycles" value="idle_cycles_match_mcpat"/>
+ <stat name="busy_cycles" value="busy_cycles_match_mcpat"/>
+ <!--This page size(B) is complete different from the page size in Main memo secction. this page size is the size of
+ virtual memory from OS/Archi perspective; the page size in Main memo secction is the actuall physical line in a DRAM bank -->
+ <!-- *********************** cores ******************* -->
+ <component id="system.core0" name="core0">
+ <!-- Core property -->
+ <param name="clock_rate" value="700"/>
+ <param name="instruction_length" value="32"/>
+ <param name="opcode_width" value="9"/>
+ <!-- address width determins the tag_width in Cache, LSQ and buffers in cache controller
+ default value is machine_bits, if not set -->
+ <param name="machine_type" value="1"/><!-- 1 inorder; 0 OOO-->
+ <!-- inorder/OoO -->
+ <param name="number_hardware_threads" value="32"/>
+ <!-- number_instruction_fetch_ports(icache ports) is always 1 in single-thread processor,
+ it only may be more than one in SMT processors. BTB ports always equals to fetch ports since
+ branch information in consective branch instructions in the same fetch group can be read out from BTB once.-->
+ <param name="fetch_width" value="1"/>
+ <!-- fetch_width determins the size of cachelines of L1 cache block -->
+ <param name="number_instruction_fetch_ports" value="1"/>
+ <param name="decode_width" value="1"/>
+ <!-- decode_width determins the number of ports of the
+ renaming table (both RAM and CAM) scheme -->
+ <param name="issue_width" value="2"/>
+ <!-- issue_width determins the number of ports of Issue window and other logic
+ as in the complexity effective proccessors paper; issue_width==dispatch_width -->
+ <param name="commit_width" value="2"/>
+ <!-- commit_width determins the number of ports of register files -->
+ <param name="fp_issue_width" value="1"/>
+ <param name="prediction_width" value="0"/>
+ <!-- number of branch instructions can be predicted simultannouesl-->
+ <!-- Current version of McPAT does not distinguish int and floating point pipelines
+ Theses parameters are reserved for future use.-->
+ <param name="pipelines_per_core" value="1,1"/>
+ <!--integer_pipeline and floating_pipelines, if the floating_pipelines is 0, then the pipeline is shared-->
+ <param name="pipeline_depth" value="8,8"/>
+ <!-- pipeline depth of int and fp, if pipeline is shared, the second number is the average cycles of fp ops -->
+ <!-- issue and exe unit-->
+ <param name="ALU_per_core" value="32"/>
+ <!-- contains an adder, a shifter, and a logical unit -->
+ <param name="MUL_per_core" value="4"/>
+ <!-- For MUL and Div -->
+ <param name="FPU_per_core" value="32"/>
+ <!-- buffer between IF and ID stage -->
+ <param name="instruction_buffer_size" value="1"/>
+ <!-- buffer between ID and sche/exe stage -->
+ <param name="decoded_stream_buffer_size" value="1"/>
+ <param name="instruction_window_scheme" value="0"/><!-- 0 PHYREG based, 1 RSBASED-->
+ <!-- McPAT support 2 types of OoO cores, RS based and physical reg based-->
+ <param name="instruction_window_size" value="1"/>
+ <param name="fp_instruction_window_size" value="1"/>
+ <!-- the instruction issue Q as in Alpha 21264; The RS as in Intel P6 -->
+ <param name="ROB_size" value="0"/>
+ <!-- each in-flight instruction has an entry in ROB -->
+ <!-- registers -->
+ <!-- SM parameters Added by Syed Gilani -->
+ <param name="rf_banks" value="32"/>
+ <param name="simd_width" value="32"/>
+ <param name="collector_units" value="32"/>
+ <param name="core_clock_ratio" value="2"/>
+ <param name="warp_size" value="32"/>
+
+ <param name="archi_Regs_IRF_size" value="65536"/>
+ <param name="archi_Regs_FRF_size" value="32"/>
+ <!-- if OoO processor, phy_reg number is needed for renaming logic,
+ renaming logic is for both integer and floating point insts. -->
+ <param name="phy_Regs_IRF_size" value="32"/>
+ <param name="phy_Regs_FRF_size" value="32"/>
+ <!-- rename logic -->
+ <param name="rename_scheme" value="0"/>
+ <!-- can be RAM based(0) or CAM based(1) rename scheme
+ RAM-based scheme will have free list, status table;
+ CAM-based scheme have the valid bit in the data field of the CAM
+ both RAM and CAM need RAM-based checkpoint table, checkpoint_depth=# of in_flight instructions;
+ Detailed RAT Implementation see TR -->
+ <param name="register_windows_size" value="0"/>
+ <!-- how many windows in the windowed register file, sun processors;
+ no register windowing is used when this number is 0 -->
+ <!-- In OoO cores, loads and stores can be issued whether inorder(Pentium Pro) or (OoO)out-of-order(Alpha),
+ They will always try to exeute out-of-order though. -->
+ <param name="LSU_order" value="inorder"/>
+ <param name="store_buffer_size" value="32"/>
+ <!-- By default, in-order cores do not have load buffers -->
+ <param name="load_buffer_size" value="32"/>
+ <!-- number of ports refer to sustainable concurrent memory accesses -->
+ <param name="memory_ports" value="2"/>
+ <!-- max_allowed_in_flight_memo_instructions determins the # of ports of load and store buffer
+ as well as the ports of Dcache which is connected to LSU -->
+ <!-- dual-pumped Dcache can be used to save the extra read/write ports -->
+ <param name="RAS_size" value="1"/>
+ <!-- general stats, defines simulation periods;require total, idle, and busy cycles for senity check -->
+ <!-- please note: if target architecture is X86, then all the instrucions refer to (fused) micro-ops -->
+ <stat name="total_instructions" value="total_instructions_match_mcpat"/>
+ <stat name="int_instructions" value="int_instruction_match_mcpat"/>
+ <stat name="fp_instructions" value="flt_instruction_match_mcpat"/>
+ <stat name="branch_instructions" value="branch_instruction_match_mcpat"/>
+ <stat name="branch_mispredictions" value="0"/>
+ <stat name="load_instructions" value="load_instruction_match_mcpat"/>
+ <stat name="store_instructions" value="store_instruction_match_mcpat"/>
+ <stat name="committed_instructions" value="total_instructions_match_mcpat"/>
+ <stat name="committed_int_instructions" value="int_instruction_match_mcpat"/>
+ <stat name="committed_fp_instructions" value="flt_instruction_match_mcpat"/>
+ <stat name="pipeline_duty_cycle" value="0.6"/><!--<=1, runtime_ipc/peak_ipc; averaged for all cores if homogenous -->
+ <!-- the following cycle stats are used for heterogeneouse cores only,
+ please ignore them if homogeneouse cores -->
+ <stat name="total_cycles" value="total_cycles_match_mcpat"/>
+ <stat name="idle_cycles" value="idle_cycles_match_mcpat"/>
+ <stat name="busy_cycles" value="busy_cycles_match_mcpat"/>
+ <!-- instruction buffer stats -->
+ <!-- ROB stats, both RS and Phy based OoOs have ROB
+ performance simulator should capture the difference on accesses,
+ otherwise, McPAT has to guess based on number of commited instructions. -->
+ <stat name="ROB_reads" value="263886"/>
+ <stat name="ROB_writes" value="263886"/>
+ <!-- RAT accesses -->
+ <stat name="rename_accesses" value="263886"/>
+ <stat name="fp_rename_accesses" value="263886"/>
+ <!-- decode and rename stage use this, should be total ic - nop -->
+ <!-- Inst window stats -->
+ <stat name="inst_window_reads" value="263886"/>
+ <stat name="inst_window_writes" value="263886"/>
+ <stat name="inst_window_wakeup_accesses" value="263886"/>
+ <stat name="fp_inst_window_reads" value="263886"/>
+ <stat name="fp_inst_window_writes" value="263886"/>
+ <stat name="fp_inst_window_wakeup_accesses" value="263886"/>
+ <!-- RF accesses -->
+ <stat name="int_regfile_reads" value="int_register_read_access_match_mcpat"/>
+ <stat name="float_regfile_reads" value="int_register_write_access_match_mcpat"/>
+ <stat name="int_regfile_writes" value="float_register_read_access_match_mcpat"/>
+ <stat name="float_regfile_writes" value="float_register_write_access_match_mcpat"/>
+
+ <!-- The following stat is for operand collector power - Added by Syed -->
+ <stat name="non_rf_operands" value="0"/>
+
+ <!-- accesses to the working reg -->
+ <stat name="function_calls" value="0"/>
+ <stat name="context_switches" value="0"/> <!--not used in the McPAT -->
+ <!-- Number of Windowes switches (number of function calls and returns)-->
+ <!-- Alu stats by default, the processor has one FPU that includes the divider and
+ multiplier. The fpu accesses should include accesses to multiplier and divider -->
+ <stat name="ialu_accesses" value="ialu_accesses_match_mcpat"/>
+ <stat name="fpu_accesses" value="fpu_accesses_match_mcpat"/>
+ <stat name="mul_accesses" value="mul_accesses_match_mcpat"/>
+ <stat name="cdb_alu_accesses" value="0"/>
+ <stat name="cdb_mul_accesses" value="0"/>
+ <stat name="cdb_fpu_accesses" value="0"/>
+ <!-- multiple cycle accesses should be counted multiple times,
+ otherwise, McPAT can use internal counter for different floating point instructions
+ to get final accesses. But that needs detailed info for floating point inst mix -->
+ <!-- currently the performance simulator should
+ make sure all the numbers are final numbers,
+ including the explicit read/write accesses,
+ and the implicite accesses such as replacements and etc.
+ Future versions of McPAT may be able to reason the implicite access
+ based on param and stats of last level cache
+ The same rule applies to all cache access stats too! -->
+ <!-- following is AF for max power computation.
+ Do not change them, unless you understand them-->
+ <stat name="IFU_duty_cycle" value="0.25"/>
+ <stat name="LSU_duty_cycle" value="0.25"/>
+ <stat name="MemManU_I_duty_cycle" value="1"/>
+ <stat name="MemManU_D_duty_cycle" value="0.25"/>
+ <stat name="ALU_duty_cycle" value="0.9"/>
+ <stat name="MUL_duty_cycle" value="0.5"/>
+ <stat name="FPU_duty_cycle" value="1"/><!-- FPU numbers are already average -->
+ <stat name="ALU_cdb_duty_cycle" value="0.9"/>
+ <stat name="MUL_cdb_duty_cycle" value="0.5"/>
+ <stat name="FPU_cdb_duty_cycle" value="15"/>
+ <component id="system.core0.predictor" name="PBT">
+ <!-- branch predictor; tournament predictor see Alpha implementation -->
+ <param name="local_predictor_size" value="10,3"/>
+ <param name="local_predictor_entries" value="1024"/>
+ <param name="global_predictor_entries" value="4096"/>
+ <param name="global_predictor_bits" value="2"/>
+ <param name="chooser_predictor_entries" value="4096"/>
+ <param name="chooser_predictor_bits" value="2"/>
+ <!-- These parameters can be combined like below in next version
+ <param name="load_predictor" value="10,3,1024"/>
+ <param name="global_predictor" value="4096,2"/>
+ <param name="predictor_chooser" value="4096,2"/>
+ -->
+ </component>
+ <component id="system.core0.itlb" name="itlb">
+ <param name="number_entries" value="1"/>
+ <stat name="total_accesses" value="0"/>
+ <stat name="total_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <!-- there is no write requests to itlb although writes happen to itlb after miss,
+ which is actually a replacement -->
+ </component>
+ <component id="system.core0.icache" name="icache">
+ <!-- there is no write requests to itlb although writes happen to it after miss,
+ which is actually a replacement -->
+ <param name="icache_config" value="16384,128,4,1,1,3,8,0"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <!-- cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate -->
+ <param name="buffer_sizes" value="16, 16, 16,0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="total_instructions_match_mcpat"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.dtlb" name="dtlb">
+ <param name="number_entries" value="1"/>
+ <stat name="total_accesses" value="0"/>
+ <stat name="total_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.ccache" name="ccache">
+ <!-- all the buffer related are optional -->
+ <param name="ccache_config" value="16384,64,2,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="ccache_read_accesses_match_mcpat"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="ccache_read_misses_match_mcpat"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.tcache" name="tcache">
+ <!-- all the buffer related are optional -->
+ <param name="tcache_config" value="49152,128,8,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="tcache_read_accesses_match_mcpat"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="tcache_read_misses_match_mcpat"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <!--model the shared memory by mimicing dcache-->
+ <component id="system.core0.sharedmemory" name="sharedmemory">
+ <!-- all the buffer related are optional -->
+ <param name="sharedmemory_config" value="98304,16,1,16,1,3,16,0"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="sharedmemory_read_access_match_mcpat"/>
+ <stat name="write_accesses" value="sharedmemory_write_access_match_mcpat"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.dcache" name="dcache">
+ <!-- all the buffer related are optional -->
+ <param name="dcache_config" value="16384,32,4,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="dcache_read_access_match_mcpat"/>
+ <stat name="write_accesses" value="dcache_write_access_match_mcpat"/>
+ <stat name="read_misses" value="dcache_read_miss_match_mcpat"/>
+ <stat name="write_misses" value="dcache_write_miss_match_mcpat"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.BTB" name="BTB">
+ <!-- all the buffer related are optional -->
+ <param name="BTB_config" value="8192,4,2,1, 1,3"/>
+ <!-- the parameters are capacity,block_width,associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ </component>
+ </component>
+ <component id="system.L1Directory0" name="L1Directory0">
+ <param name="Directory_type" value="0"/>
+ <!--0 cam based shadowed tag. 1 directory cache -->
+ <param name="Dir_config" value="2048,1,0,1, 4, 4,8"/>
+ <!-- the parameters are capacity,block_width, associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ <param name="buffer_sizes" value="8, 8, 8, 8"/>
+ <!-- all the buffer related are optional -->
+ <param name="clockrate" value="1400"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw search ports -->
+ <param name="device_type" value="0"/>
+ <!-- altough there are multiple access types,
+ Performance simulator needs to cast them into reads or writes
+ e.g. the invalidates can be considered as writes -->
+ <stat name="read_accesses" value="800000"/>
+ <stat name="write_accesses" value="27276"/>
+ <stat name="read_misses" value="1632"/>
+ <stat name="write_misses" value="183"/>
+ <stat name="conflicts" value="20"/>
+ <stat name="duty_cycle" value="0.45"/>
+ </component>
+ <component id="system.L2Directory0" name="L2Directory0">
+ <param name="Directory_type" value="1"/>
+ <!--0 cam based shadowed tag. 1 directory cache -->
+ <param name="Dir_config" value="1048576,16,16,1,2, 100"/>
+ <!-- the parameters are capacity,block_width, associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ <param name="buffer_sizes" value="8, 8, 8, 8"/>
+ <!-- all the buffer related are optional -->
+ <param name="clockrate" value="1400"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw search ports -->
+ <param name="device_type" value="0"/>
+ <!-- altough there are multiple access types,
+ Performance simulator needs to cast them into reads or writes
+ e.g. the invalidates can be considered as writes -->
+ <stat name="read_accesses" value="0"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.45"/>
+ </component>
+ <component id="system.L20" name="L20">
+ <!-- all the buffer related are optional -->
+ <param name="L2_config" value="131072,128,16,1, 4,23, 64, 1"/>
+ <!-- consider 4-way bank interleaving for Niagara 1 -->
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <param name="clockrate" value="2962"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw ports -->
+ <param name="device_type" value="0"/>
+ <stat name="read_accesses" value="200000"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.5"/>
+ </component>
+
+<!--**********************************************************************-->
+<component id="system.L30" name="L30">
+ <param name="L3_config" value="1048576,64,16,1, 2,100, 64,1"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="clockrate" value="3500"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw ports -->
+ <param name="device_type" value="0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="58824"/>
+ <stat name="write_accesses" value="27276"/>
+ <stat name="read_misses" value="1632"/>
+ <stat name="write_misses" value="183"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.35"/>
+ </component>
+
+
+<!--**********************************************************************-->
+ <component id="system.NoC0" name="noc0">
+ <param name="clockrate" value="700"/>
+ <param name="type" value="1"/>
+ <!-- 1 NoC, O bus -->
+ <param name="horizontal_nodes" value="2"/>
+ <param name="vertical_nodes" value="1"/>
+ <param name="has_global_link" value="0"/>
+ <!-- 1 has global link, 0 does not have global link -->
+ <param name="link_throughput" value="1"/><!--w.r.t clock -->
+ <param name="link_latency" value="1"/><!--w.r.t clock -->
+ <!-- througput >= latency -->
+ <!-- Router architecture -->
+ <param name="input_ports" value="6"/>
+ <param name="output_ports" value="6"/>
+ <param name="virtual_channel_per_port" value="1"/>
+ <!-- input buffer; in classic routers only input ports need buffers -->
+ <param name="flit_bits" value="32"/>
+ <param name="input_buffer_entries_per_vc" value="1"/><!--VCs within the same ports share input buffers whose size is propotional to the number of VCs-->
+ <param name="chip_coverage" value="1"/>
+ <!-- When multiple NOC present, one NOC will cover part of the whole chip. chip_coverage <=1 -->
+ <stat name="total_accesses" value="0"/>
+ <!-- This is the number of total accesses within the whole network not for each router -->
+ <stat name="duty_cycle" value="0.6"/>
+ </component>
+<!--**********************************************************************-->
+<!--**********************************************************************-->
+
+ <component id="system.mem" name="mem">
+ <!-- Main memory property -->
+ <param name="mem_tech_node" value="23"/>
+ <param name="device_clock" value="200"/><!--MHz, this is clock rate of the actual memory device, not the FSB -->
+ <param name="peak_transfer_rate" value="3200"/><!--MB/S-->
+ <param name="internal_prefetch_of_DRAM_chip" value="4"/>
+ <!-- 2 for DDR, 4 for DDR2, 8 for DDR3...-->
+ <!-- the device clock, peak_transfer_rate, and the internal prefetch decide the DIMM property -->
+ <!-- above numbers can be easily found from Wikipedia -->
+ <param name="capacity_per_channel" value="4096"/> <!-- MB -->
+ <!-- capacity_per_Dram_chip=capacity_per_channel/number_of_dimms/number_ranks/Dram_chips_per_rank
+ Current McPAT assumes single DIMMs are used.-->
+ <param name="number_ranks" value="2"/>
+ <param name="num_banks_of_DRAM_chip" value="6"/>
+ <param name="Block_width_of_DRAM_chip" value="64"/> <!-- B -->
+ <param name="output_width_of_DRAM_chip" value="8"/>
+ <!--number of Dram_chips_per_rank=" 72/output_width_of_DRAM_chip-->
+ <!--number of Dram_chips_per_rank=" 72/output_width_of_DRAM_chip-->
+ <param name="page_size_of_DRAM_chip" value="8"/> <!-- 8 or 16 -->
+ <param name="burstlength_of_DRAM_chip" value="8"/>
+ <stat name="memory_accesses" value="1052"/>
+ <stat name="memory_reads" value="1052"/>
+ <stat name="memory_writes" value="1052"/>
+ </component>
+ <component id="system.mc" name="mc">
+ <!-- Memeory controllers are for DDR(2,3...) DIMMs -->
+ <!-- current version of McPAT uses published values for base parameters of memory controller
+ improvments on MC will be added in later versions. -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="mc_clock" value="1848"/><!--DIMM IO bus clock rate MHz DDR2-400 for Niagara 1-->
+ <param name="peak_transfer_rate" value="29568"/><!--MB/S Syed: GTX 470 has 177.4GB/s mem transfer rate with 6 MCs -->
+ <param name="block_size" value="64"/><!--B-->
+ <param name="number_mcs" value="6"/><!-- 6 GDDR5 memory controllers -->
+ <!-- current McPAT only supports homogeneous memory controllers -->
+ <param name="memory_channels_per_mc" value="2"/>
+ <param name="number_ranks" value="1"/>
+ <param name="withPHY" value="0"/>
+ <!-- # of ranks of each channel-->
+ <param name="req_window_size_per_channel" value="16"/>
+ <param name="IO_buffer_size_per_channel" value="16"/>
+ <param name="databus_width" value="32"/>
+ <param name="addressbus_width" value="32"/>
+ <param name="PRT_entries" value="32"/>
+ <!-- # of empirical DRAM model parameter -->
+ <param name="dram_cmd_coeff" value="0"/>
+ <param name="dram_act_coeff" value="0"/>
+ <param name="dram_nop_coeff" value="0"/>
+ <param name="dram_activity_coeff" value="0"/>
+ <param name="dram_pre_coeff" value="3.8475e-8f"/>
+ <param name="dram_rd_coeff" value="7.74707143e-8f"/>
+ <param name="dram_wr_coeff" value="3.54664286e-8f"/>
+ <param name="dram_req_coeff" value="0"/>
+ <param name="dram_const_coeff" value="0"/>
+
+ <!-- McPAT will add the control bus width to the addressbus width automatically -->
+ <stat name="memory_accesses" value="memory_accesses_match_mcpat"/>
+ <stat name="memory_reads" value="memory_reads_match_mcpat"/>
+ <stat name="memory_writes" value="memory_writes_match_mcpat"/>
+ <!-- McPAT does not track individual mc, instead, it takes the total accesses and calculate
+ the average power per MC or per channel. This is sufficent for most application.
+ Further trackdown can be easily added in later versions. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.niu" name="niu">
+ <!-- On chip 10Gb Ethernet NIC, including XAUI Phy and MAC controller -->
+ <!-- For a minimum IP packet size of 84B at 10Gb/s, a new packet arrives every 67.2ns.
+ the low bound of clock rate of a 10Gb MAC is 150Mhz -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="clockrate" value="350"/>
+ <param name="number_units" value="0"/> <!-- unlike PCIe and memory controllers, each Ethernet controller only have one port -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- ratio of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual nic, instead, it takes the total accesses and calculate
+ the average power per nic or per channel. This is sufficent for most application. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.pcie" name="pcie">
+ <!-- On chip PCIe controller, including Phy-->
+ <!-- For a minimum PCIe packet size of 84B at 8Gb/s per lane (PCIe 3.0), a new packet arrives every 84ns.
+ the low bound of clock rate of a PCIe per lane logic is 120Mhz -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="withPHY" value="1"/>
+ <param name="clockrate" value="350"/>
+ <param name="number_units" value="0"/>
+ <param name="num_channels" value="8"/> <!-- 2 ,4 ,8 ,16 ,32 -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- Percentage of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual pcie controllers, instead, it takes the total accesses and calculate
+ the average power per pcie controller or per channel. This is sufficent for most application. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.flashc" name="flashc">
+ <param name="number_flashcs" value="0"/>
+ <param name="type" value="1"/> <!-- 1: low power; 0 high performance -->
+ <param name="withPHY" value="1"/>
+ <param name="peak_transfer_rate" value="200"/><!--Per controller sustainable reak rate MB/S -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- Percentage of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual flash controller, instead, it takes the total accesses and calculate
+ the average power per fc or per channel. This is sufficent for most application -->
+ </component>
+<!--**********************************************************************-->
+
+ </component>
+</component>
\ No newline at end of file diff --git a/configs/tested-cfgs/SM7_GV100/accelwattch_ptx_sim_alt.xml b/configs/tested-cfgs/SM7_GV100/accelwattch_ptx_sim_alt.xml new file mode 100644 index 0000000..0c6f211 --- /dev/null +++ b/configs/tested-cfgs/SM7_GV100/accelwattch_ptx_sim_alt.xml @@ -0,0 +1,623 @@ +<?xml version="1.0" ?>
+<component id="root" name="root">
+ <component id="system" name="system">
+<!-- Copyright (c) 2018-2021, Vijay Kandiah, Junrui Pan, Mahmoud Khairy, Scott Peverelle, Timothy Rogers, Tor M. Aamodt, Nikos Hardavellas
+Northwestern University, Purdue University, The University of British Columbia
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer;
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution;
+3. Neither the names of Northwestern University, Purdue University,
+ The University of British Columbia nor the names of their contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE. -->
+
+ <!-- DYNAMIC Power Activity Factors -->
+
+ <param name="TOT_INST" value="2" /> <!--Instruction Buffer Activity Factor(Total Warp Instructions)-->
+ <param name="FP_INT" value="4.57" /> <!--Scheduler Activity Factor(Non-Memory Warp Instructons)-->
+ <param name="IC_H" value="8.827711067" /> <!--Instruction Cache Hits -->
+ <param name="IC_M" value="8.827711067" /> <!--Instruction Cache Misses-->
+ <param name="DC_RH" value="8.545163843" /> <!--L1 Data Cache Read Hits-->
+ <param name="DC_RM" value="8.545163843" /> <!--L1 Data Cache Read Misses-->
+ <param name="DC_WH" value="8.545163843" /> <!--L1 Data Cache Write Hits-->
+ <param name="DC_WM" value="8.545163843" /> <!--L1 Data Cache Write Misses-->
+ <param name="CC_H" value="0.65916315" /> <!--Constant Cache Hits-->
+ <param name="CC_M" value="0.73418985" /> <!--Constant Cache Misses-->
+ <param name="SHRD_ACC" value="1.763326296" /> <!--Shared Memory Accesses-->
+ <param name="REG_RD" value="0.126123699" /> <!--Register Reads-->
+ <param name="REG_WR" value="0.126123699" /> <!--Register Writes-->
+ <param name="INT_ACC" value="2.851008299" /> <!--Integer ALU Accesses-->
+ <param name="FP_ACC" value="0.723984758" /> <!--FPU Accesses-->
+ <param name="DP_ACC" value="0.723979435" /> <!--Integer Accesses-->
+ <param name="INT_MUL_ACC" value="0.119939033" /> <!--Integer MUL Accesses-->
+ <param name="FP_MUL_ACC" value="0.147036868" /> <!--FP MUL Accesses-->
+ <param name="FP_SQRT_ACC" value="1.234782354" /> <!--SFU: sqrt Accesses-->
+ <param name="FP_LG_ACC" value="0.594393568" /> <!--SFU: log Accesses-->
+ <param name="FP_SIN_ACC" value="0.147037283" /> <!--SFU: sin/cos Accesses-->
+ <param name="FP_EXP_ACC" value="0.920933945" /> <!--SFU: exponent Accesses-->
+ <param name="DP_MUL_ACC" value="0.18425577" /> <!--DP MUL Accesses-->
+ <param name="TENSOR_ACC" value="1.656666667" /> <!--Tensor Accesses-->
+ <param name="TEX_ACC" value="0.147036868" /> <!--Texture Unit Accesses-->
+ <param name="MEM_RD" value="0.03058335" /> <!--DRAM Reads-->
+ <param name="MEM_WR" value="0.03058335" /> <!--DRAM Writes-->
+ <param name="MEM_PRE" value="0.03058335" /> <!--DRAM Precharge-->
+ <param name="L2_RH" value="2.032318132" /> <!--L2 Data Cache Read Hits-->
+ <param name="L2_RM" value="2.032318132" /> <!--L2 Data Cache Read Misses-->
+ <param name="L2_WH" value="2.032318132" /> <!--L2 Data Cache Write Hits-->
+ <param name="L2_WM" value="2.032318132" /> <!--L2 Data Cache Write Misses-->
+ <param name="NOC_A" value="70.15055938" /> <!--Interconnect Network Accesses-->
+ <param name="PIPE_A" value="0.01" /> <!--Pipeline Accesses-->
+
+ <!-- PTX Model specific DYNAMIC Power Activity Factors-->
+
+ <param name="TC_H" value="0.1" /> <!--Texture Cache Hits-->
+ <param name="TC_M" value="0.1" /> <!--Texture Cache Misses-->
+ <param name="INT_MUL24_ACC" value="0.235290825" /> <!--Integer 24-bit MUL Accesses-->
+ <param name="INT_MUL32_ACC" value="0.250616643" /> <!--Integer 32-bit MUL Accesses-->
+ <param name="INT_DIV_ACC" value="5.327155759" /> <!--Integer DIV Accesses-->
+ <param name="FP_DIV_ACC" value="4.992722677" /> <!--FP DIV Accesses-->
+ <param name="DP_DIV_ACC" value="26.46013946" /> <!--DP DIV Accesses-->
+
+ <!-- STATIC & CONSTANT Power -->
+
+ <param name="constant_power" value="32.32522272" /> <!--Constant power-->
+ <param name="idle_core_power" value="0.28279166"/> <!--Idle SM power-->
+
+ <param name="static_cat1_flane" value="15.29035866"/> <!--INT (ADD+MUL) First Lane Activation Power-->
+ <param name="static_cat1_addlane" value="0.586233603"/> <!--INT (ADD+MUL) Additional Lane Activation Power-->
+
+ <param name="static_cat2_flane" value="18.6179906"/> <!--INT+FP First Lane Activation Power-->
+ <param name="static_cat2_addlane" value="0.645228013"/> <!--INT+FP Additional Lane Activation Power-->
+
+ <param name="static_cat3_flane" value="19.10017723"/> <!--INT+FP+DP First Lane Activation Power-->
+ <param name="static_cat3_addlane" value="0.726863055"/> <!--INT+FP+DP Additional Lane Activation Power-->
+
+ <param name="static_cat4_flane" value="18.55029744"/> <!--INT+FP+SFU First Lane Activation Power-->
+ <param name="static_cat4_addlane" value="0.6099397"/> <!--INT+FP+SFU Additional Lane Activation Power-->
+
+ <param name="static_cat5_flane" value="14.74826681"/> <!--INT+FP+TEX First Lane Activation Power-->
+ <param name="static_cat5_addlane" value="0.514367937"/> <!--INT+FP+TEX Additional Lane Activation Power-->
+
+ <param name="static_cat6_flane" value="48.94875596"/> <!--INT+FP+TENSOR First Lane Activation Power-->
+ <param name="static_cat6_addlane" value="0.0"/> <!--INT+FP+TENSOR Additional Lane Activation Power-->
+
+ <param name="static_light_flane" value="1.965373811"/> <!--LIGHT_SM First Lane Activation Power-->
+ <param name="static_light_addlane" value="0.003966868"/> <!--LIGHT_SM Additional Lane Activation Power-->
+
+ <param name="static_intadd_flane" value="19.70468506"/> <!--INT ADD First Lane Activation Power-->
+ <param name="static_intadd_addlane" value="0.388578623"/> <!--INT ADD Additional Lane Activation Power-->
+
+ <param name="static_intmul_flane" value="16.64811823"/> <!--INT MUL First Lane Activation Power-->
+ <param name="static_intmul_addlane" value="0.281803166"/> <!--INT MUL Additional Lane Activation Power-->
+
+ <param name="static_geomean_flane" value="17.21745077"/> <!--GEOMEAN First Lane Activation Power-->
+ <param name="static_geomean_addlane" value="0.650630555"/> <!--GEOMEAN Additional Lane Activation Power-->
+ <param name="static_shared_flane" value="31.40965691"/> <!--Shared Memory First Lane Activation Power-->
+ <param name="static_l1_flane" value="34.79491352"/> <!--L1D First Lane Activation Power-->
+ <param name="static_l2_flane" value="17.30654755"/> <!--L2D ADD+MUL First Lane Activation Power-->
+
+
+ <!-- LEAVE BELOW UNCHANGED! These are parameters used for initial GPUWattch model left untouched -->
+
+
+ <param name="GPU_Architecture" value="1"/><!-- 0-G80; 1-Fermi; others not supported -->
+ <param name="architecture" value="1"/> <!-- fermi:1 quadro:2 other: undefined-->
+ <param name="number_of_L1Directories" value="0"/>
+ <param name="number_of_L2Directories" value="0"/>
+ <param name="number_of_L2s" value="1"/> <!-- This number means how many L2 clusters in each cluster there can be multiple banks/ports -->
+ <param name="number_of_L3s" value="0"/> <!-- This number means how many L3 clusters -->
+ <param name="number_of_NoCs" value="1"/>
+ <param name="homogeneous_cores" value="1"/><!--1 means homo -->
+ <param name="homogeneous_L2s" value="1"/>
+ <param name="homogeneous_L1Directorys" value="1"/>
+ <param name="homogeneous_L2Directorys" value="1"/>
+ <param name="homogeneous_L3s" value="1"/>
+ <param name="homogeneous_ccs" value="1"/><!--cache coherece hardware -->
+ <param name="homogeneous_NoCs" value="1"/>
+ <param name="core_tech_node" value="23"/><!-- nm -->
+
+ <param name="number_cache_levels" value="2"/>
+ <param name="interconnect_projection_type" value="0"/><!--0: agressive wire technology; 1: conservative wire technology -->
+ <param name="device_type" value="0"/><!--0: HP(High Performance Type); 1: LSTP(Low standby power) 2: LOP (Low Operating Power) -->
+ <param name="longer_channel_device" value="1"/><!-- 0 no use; 1 use when possible -->
+ <param name="machine_bits" value="32"/>
+ <param name="virtual_address_width" value="32"/>
+ <param name="physical_address_width" value="32"/>
+ <param name="virtual_memory_page_size" value="4096"/>
+
+ <param name="IDLE_CORE_N" value="1"/>
+ <stat name="num_idle_cores" value="0"/><!-- Average Number of idle cores during this period -->
+ <stat name="total_cycles" value="total_cycles_match_mcpat"/>
+ <stat name="idle_cycles" value="idle_cycles_match_mcpat"/>
+ <stat name="busy_cycles" value="busy_cycles_match_mcpat"/>
+ <!--This page size(B) is complete different from the page size in Main memo secction. this page size is the size of
+ virtual memory from OS/Archi perspective; the page size in Main memo secction is the actuall physical line in a DRAM bank -->
+ <!-- *********************** cores ******************* -->
+ <component id="system.core0" name="core0">
+ <!-- Core property -->
+ <param name="clock_rate" value="700"/>
+ <param name="instruction_length" value="32"/>
+ <param name="opcode_width" value="9"/>
+ <!-- address width determins the tag_width in Cache, LSQ and buffers in cache controller
+ default value is machine_bits, if not set -->
+ <param name="machine_type" value="1"/><!-- 1 inorder; 0 OOO-->
+ <!-- inorder/OoO -->
+ <param name="number_hardware_threads" value="32"/>
+ <!-- number_instruction_fetch_ports(icache ports) is always 1 in single-thread processor,
+ it only may be more than one in SMT processors. BTB ports always equals to fetch ports since
+ branch information in consective branch instructions in the same fetch group can be read out from BTB once.-->
+ <param name="fetch_width" value="1"/>
+ <!-- fetch_width determins the size of cachelines of L1 cache block -->
+ <param name="number_instruction_fetch_ports" value="1"/>
+ <param name="decode_width" value="1"/>
+ <!-- decode_width determins the number of ports of the
+ renaming table (both RAM and CAM) scheme -->
+ <param name="issue_width" value="2"/>
+ <!-- issue_width determins the number of ports of Issue window and other logic
+ as in the complexity effective proccessors paper; issue_width==dispatch_width -->
+ <param name="commit_width" value="2"/>
+ <!-- commit_width determins the number of ports of register files -->
+ <param name="fp_issue_width" value="1"/>
+ <param name="prediction_width" value="0"/>
+ <!-- number of branch instructions can be predicted simultannouesl-->
+ <!-- Current version of McPAT does not distinguish int and floating point pipelines
+ Theses parameters are reserved for future use.-->
+ <param name="pipelines_per_core" value="1,1"/>
+ <!--integer_pipeline and floating_pipelines, if the floating_pipelines is 0, then the pipeline is shared-->
+ <param name="pipeline_depth" value="8,8"/>
+ <!-- pipeline depth of int and fp, if pipeline is shared, the second number is the average cycles of fp ops -->
+ <!-- issue and exe unit-->
+ <param name="ALU_per_core" value="32"/>
+ <!-- contains an adder, a shifter, and a logical unit -->
+ <param name="MUL_per_core" value="4"/>
+ <!-- For MUL and Div -->
+ <param name="FPU_per_core" value="32"/>
+ <!-- buffer between IF and ID stage -->
+ <param name="instruction_buffer_size" value="1"/>
+ <!-- buffer between ID and sche/exe stage -->
+ <param name="decoded_stream_buffer_size" value="1"/>
+ <param name="instruction_window_scheme" value="0"/><!-- 0 PHYREG based, 1 RSBASED-->
+ <!-- McPAT support 2 types of OoO cores, RS based and physical reg based-->
+ <param name="instruction_window_size" value="1"/>
+ <param name="fp_instruction_window_size" value="1"/>
+ <!-- the instruction issue Q as in Alpha 21264; The RS as in Intel P6 -->
+ <param name="ROB_size" value="0"/>
+ <!-- each in-flight instruction has an entry in ROB -->
+ <!-- registers -->
+ <!-- SM parameters Added by Syed Gilani -->
+ <param name="rf_banks" value="32"/>
+ <param name="simd_width" value="32"/>
+ <param name="collector_units" value="32"/>
+ <param name="core_clock_ratio" value="2"/>
+ <param name="warp_size" value="32"/>
+
+ <param name="archi_Regs_IRF_size" value="65536"/>
+ <param name="archi_Regs_FRF_size" value="32"/>
+ <!-- if OoO processor, phy_reg number is needed for renaming logic,
+ renaming logic is for both integer and floating point insts. -->
+ <param name="phy_Regs_IRF_size" value="32"/>
+ <param name="phy_Regs_FRF_size" value="32"/>
+ <!-- rename logic -->
+ <param name="rename_scheme" value="0"/>
+ <!-- can be RAM based(0) or CAM based(1) rename scheme
+ RAM-based scheme will have free list, status table;
+ CAM-based scheme have the valid bit in the data field of the CAM
+ both RAM and CAM need RAM-based checkpoint table, checkpoint_depth=# of in_flight instructions;
+ Detailed RAT Implementation see TR -->
+ <param name="register_windows_size" value="0"/>
+ <!-- how many windows in the windowed register file, sun processors;
+ no register windowing is used when this number is 0 -->
+ <!-- In OoO cores, loads and stores can be issued whether inorder(Pentium Pro) or (OoO)out-of-order(Alpha),
+ They will always try to exeute out-of-order though. -->
+ <param name="LSU_order" value="inorder"/>
+ <param name="store_buffer_size" value="32"/>
+ <!-- By default, in-order cores do not have load buffers -->
+ <param name="load_buffer_size" value="32"/>
+ <!-- number of ports refer to sustainable concurrent memory accesses -->
+ <param name="memory_ports" value="2"/>
+ <!-- max_allowed_in_flight_memo_instructions determins the # of ports of load and store buffer
+ as well as the ports of Dcache which is connected to LSU -->
+ <!-- dual-pumped Dcache can be used to save the extra read/write ports -->
+ <param name="RAS_size" value="1"/>
+ <!-- general stats, defines simulation periods;require total, idle, and busy cycles for senity check -->
+ <!-- please note: if target architecture is X86, then all the instrucions refer to (fused) micro-ops -->
+ <stat name="total_instructions" value="total_instructions_match_mcpat"/>
+ <stat name="int_instructions" value="int_instruction_match_mcpat"/>
+ <stat name="fp_instructions" value="flt_instruction_match_mcpat"/>
+ <stat name="branch_instructions" value="branch_instruction_match_mcpat"/>
+ <stat name="branch_mispredictions" value="0"/>
+ <stat name="load_instructions" value="load_instruction_match_mcpat"/>
+ <stat name="store_instructions" value="store_instruction_match_mcpat"/>
+ <stat name="committed_instructions" value="total_instructions_match_mcpat"/>
+ <stat name="committed_int_instructions" value="int_instruction_match_mcpat"/>
+ <stat name="committed_fp_instructions" value="flt_instruction_match_mcpat"/>
+ <stat name="pipeline_duty_cycle" value="0.6"/><!--<=1, runtime_ipc/peak_ipc; averaged for all cores if homogenous -->
+ <!-- the following cycle stats are used for heterogeneouse cores only,
+ please ignore them if homogeneouse cores -->
+ <stat name="total_cycles" value="total_cycles_match_mcpat"/>
+ <stat name="idle_cycles" value="idle_cycles_match_mcpat"/>
+ <stat name="busy_cycles" value="busy_cycles_match_mcpat"/>
+ <!-- instruction buffer stats -->
+ <!-- ROB stats, both RS and Phy based OoOs have ROB
+ performance simulator should capture the difference on accesses,
+ otherwise, McPAT has to guess based on number of commited instructions. -->
+ <stat name="ROB_reads" value="263886"/>
+ <stat name="ROB_writes" value="263886"/>
+ <!-- RAT accesses -->
+ <stat name="rename_accesses" value="263886"/>
+ <stat name="fp_rename_accesses" value="263886"/>
+ <!-- decode and rename stage use this, should be total ic - nop -->
+ <!-- Inst window stats -->
+ <stat name="inst_window_reads" value="263886"/>
+ <stat name="inst_window_writes" value="263886"/>
+ <stat name="inst_window_wakeup_accesses" value="263886"/>
+ <stat name="fp_inst_window_reads" value="263886"/>
+ <stat name="fp_inst_window_writes" value="263886"/>
+ <stat name="fp_inst_window_wakeup_accesses" value="263886"/>
+ <!-- RF accesses -->
+ <stat name="int_regfile_reads" value="int_register_read_access_match_mcpat"/>
+ <stat name="float_regfile_reads" value="int_register_write_access_match_mcpat"/>
+ <stat name="int_regfile_writes" value="float_register_read_access_match_mcpat"/>
+ <stat name="float_regfile_writes" value="float_register_write_access_match_mcpat"/>
+
+ <!-- The following stat is for operand collector power - Added by Syed -->
+ <stat name="non_rf_operands" value="0"/>
+
+ <!-- accesses to the working reg -->
+ <stat name="function_calls" value="0"/>
+ <stat name="context_switches" value="0"/> <!--not used in the McPAT -->
+ <!-- Number of Windowes switches (number of function calls and returns)-->
+ <!-- Alu stats by default, the processor has one FPU that includes the divider and
+ multiplier. The fpu accesses should include accesses to multiplier and divider -->
+ <stat name="ialu_accesses" value="ialu_accesses_match_mcpat"/>
+ <stat name="fpu_accesses" value="fpu_accesses_match_mcpat"/>
+ <stat name="mul_accesses" value="mul_accesses_match_mcpat"/>
+ <stat name="cdb_alu_accesses" value="0"/>
+ <stat name="cdb_mul_accesses" value="0"/>
+ <stat name="cdb_fpu_accesses" value="0"/>
+ <!-- multiple cycle accesses should be counted multiple times,
+ otherwise, McPAT can use internal counter for different floating point instructions
+ to get final accesses. But that needs detailed info for floating point inst mix -->
+ <!-- currently the performance simulator should
+ make sure all the numbers are final numbers,
+ including the explicit read/write accesses,
+ and the implicite accesses such as replacements and etc.
+ Future versions of McPAT may be able to reason the implicite access
+ based on param and stats of last level cache
+ The same rule applies to all cache access stats too! -->
+ <!-- following is AF for max power computation.
+ Do not change them, unless you understand them-->
+ <stat name="IFU_duty_cycle" value="0.25"/>
+ <stat name="LSU_duty_cycle" value="0.25"/>
+ <stat name="MemManU_I_duty_cycle" value="1"/>
+ <stat name="MemManU_D_duty_cycle" value="0.25"/>
+ <stat name="ALU_duty_cycle" value="0.9"/>
+ <stat name="MUL_duty_cycle" value="0.5"/>
+ <stat name="FPU_duty_cycle" value="1"/><!-- FPU numbers are already average -->
+ <stat name="ALU_cdb_duty_cycle" value="0.9"/>
+ <stat name="MUL_cdb_duty_cycle" value="0.5"/>
+ <stat name="FPU_cdb_duty_cycle" value="15"/>
+ <component id="system.core0.predictor" name="PBT">
+ <!-- branch predictor; tournament predictor see Alpha implementation -->
+ <param name="local_predictor_size" value="10,3"/>
+ <param name="local_predictor_entries" value="1024"/>
+ <param name="global_predictor_entries" value="4096"/>
+ <param name="global_predictor_bits" value="2"/>
+ <param name="chooser_predictor_entries" value="4096"/>
+ <param name="chooser_predictor_bits" value="2"/>
+ <!-- These parameters can be combined like below in next version
+ <param name="load_predictor" value="10,3,1024"/>
+ <param name="global_predictor" value="4096,2"/>
+ <param name="predictor_chooser" value="4096,2"/>
+ -->
+ </component>
+ <component id="system.core0.itlb" name="itlb">
+ <param name="number_entries" value="1"/>
+ <stat name="total_accesses" value="0"/>
+ <stat name="total_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <!-- there is no write requests to itlb although writes happen to itlb after miss,
+ which is actually a replacement -->
+ </component>
+ <component id="system.core0.icache" name="icache">
+ <!-- there is no write requests to itlb although writes happen to it after miss,
+ which is actually a replacement -->
+ <param name="icache_config" value="16384,128,4,1,1,3,8,0"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <!-- cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate -->
+ <param name="buffer_sizes" value="16, 16, 16,0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="total_instructions_match_mcpat"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.dtlb" name="dtlb">
+ <param name="number_entries" value="1"/>
+ <stat name="total_accesses" value="0"/>
+ <stat name="total_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.ccache" name="ccache">
+ <!-- all the buffer related are optional -->
+ <param name="ccache_config" value="16384,64,2,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="ccache_read_accesses_match_mcpat"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="ccache_read_misses_match_mcpat"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.tcache" name="tcache">
+ <!-- all the buffer related are optional -->
+ <param name="tcache_config" value="49152,128,8,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="tcache_read_accesses_match_mcpat"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="tcache_read_misses_match_mcpat"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <!--model the shared memory by mimicing dcache-->
+ <component id="system.core0.sharedmemory" name="sharedmemory">
+ <!-- all the buffer related are optional -->
+ <param name="sharedmemory_config" value="98304,16,1,16,1,3,16,0"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="sharedmemory_read_access_match_mcpat"/>
+ <stat name="write_accesses" value="sharedmemory_write_access_match_mcpat"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.dcache" name="dcache">
+ <!-- all the buffer related are optional -->
+ <param name="dcache_config" value="16384,32,4,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="dcache_read_access_match_mcpat"/>
+ <stat name="write_accesses" value="dcache_write_access_match_mcpat"/>
+ <stat name="read_misses" value="dcache_read_miss_match_mcpat"/>
+ <stat name="write_misses" value="dcache_write_miss_match_mcpat"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.BTB" name="BTB">
+ <!-- all the buffer related are optional -->
+ <param name="BTB_config" value="8192,4,2,1, 1,3"/>
+ <!-- the parameters are capacity,block_width,associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ </component>
+ </component>
+ <component id="system.L1Directory0" name="L1Directory0">
+ <param name="Directory_type" value="0"/>
+ <!--0 cam based shadowed tag. 1 directory cache -->
+ <param name="Dir_config" value="2048,1,0,1, 4, 4,8"/>
+ <!-- the parameters are capacity,block_width, associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ <param name="buffer_sizes" value="8, 8, 8, 8"/>
+ <!-- all the buffer related are optional -->
+ <param name="clockrate" value="1400"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw search ports -->
+ <param name="device_type" value="0"/>
+ <!-- altough there are multiple access types,
+ Performance simulator needs to cast them into reads or writes
+ e.g. the invalidates can be considered as writes -->
+ <stat name="read_accesses" value="800000"/>
+ <stat name="write_accesses" value="27276"/>
+ <stat name="read_misses" value="1632"/>
+ <stat name="write_misses" value="183"/>
+ <stat name="conflicts" value="20"/>
+ <stat name="duty_cycle" value="0.45"/>
+ </component>
+ <component id="system.L2Directory0" name="L2Directory0">
+ <param name="Directory_type" value="1"/>
+ <!--0 cam based shadowed tag. 1 directory cache -->
+ <param name="Dir_config" value="1048576,16,16,1,2, 100"/>
+ <!-- the parameters are capacity,block_width, associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ <param name="buffer_sizes" value="8, 8, 8, 8"/>
+ <!-- all the buffer related are optional -->
+ <param name="clockrate" value="1400"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw search ports -->
+ <param name="device_type" value="0"/>
+ <!-- altough there are multiple access types,
+ Performance simulator needs to cast them into reads or writes
+ e.g. the invalidates can be considered as writes -->
+ <stat name="read_accesses" value="0"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.45"/>
+ </component>
+ <component id="system.L20" name="L20">
+ <!-- all the buffer related are optional -->
+ <param name="L2_config" value="131072,128,16,1, 4,23, 64, 1"/>
+ <!-- consider 4-way bank interleaving for Niagara 1 -->
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <param name="clockrate" value="2962"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw ports -->
+ <param name="device_type" value="0"/>
+ <stat name="read_accesses" value="200000"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.5"/>
+ </component>
+
+<!--**********************************************************************-->
+<component id="system.L30" name="L30">
+ <param name="L3_config" value="1048576,64,16,1, 2,100, 64,1"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="clockrate" value="3500"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw ports -->
+ <param name="device_type" value="0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="58824"/>
+ <stat name="write_accesses" value="27276"/>
+ <stat name="read_misses" value="1632"/>
+ <stat name="write_misses" value="183"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.35"/>
+ </component>
+
+
+<!--**********************************************************************-->
+ <component id="system.NoC0" name="noc0">
+ <param name="clockrate" value="700"/>
+ <param name="type" value="1"/>
+ <!-- 1 NoC, O bus -->
+ <param name="horizontal_nodes" value="2"/>
+ <param name="vertical_nodes" value="1"/>
+ <param name="has_global_link" value="0"/>
+ <!-- 1 has global link, 0 does not have global link -->
+ <param name="link_throughput" value="1"/><!--w.r.t clock -->
+ <param name="link_latency" value="1"/><!--w.r.t clock -->
+ <!-- througput >= latency -->
+ <!-- Router architecture -->
+ <param name="input_ports" value="6"/>
+ <param name="output_ports" value="6"/>
+ <param name="virtual_channel_per_port" value="1"/>
+ <!-- input buffer; in classic routers only input ports need buffers -->
+ <param name="flit_bits" value="32"/>
+ <param name="input_buffer_entries_per_vc" value="1"/><!--VCs within the same ports share input buffers whose size is propotional to the number of VCs-->
+ <param name="chip_coverage" value="1"/>
+ <!-- When multiple NOC present, one NOC will cover part of the whole chip. chip_coverage <=1 -->
+ <stat name="total_accesses" value="0"/>
+ <!-- This is the number of total accesses within the whole network not for each router -->
+ <stat name="duty_cycle" value="0.6"/>
+ </component>
+<!--**********************************************************************-->
+<!--**********************************************************************-->
+
+ <component id="system.mem" name="mem">
+ <!-- Main memory property -->
+ <param name="mem_tech_node" value="23"/>
+ <param name="device_clock" value="200"/><!--MHz, this is clock rate of the actual memory device, not the FSB -->
+ <param name="peak_transfer_rate" value="3200"/><!--MB/S-->
+ <param name="internal_prefetch_of_DRAM_chip" value="4"/>
+ <!-- 2 for DDR, 4 for DDR2, 8 for DDR3...-->
+ <!-- the device clock, peak_transfer_rate, and the internal prefetch decide the DIMM property -->
+ <!-- above numbers can be easily found from Wikipedia -->
+ <param name="capacity_per_channel" value="4096"/> <!-- MB -->
+ <!-- capacity_per_Dram_chip=capacity_per_channel/number_of_dimms/number_ranks/Dram_chips_per_rank
+ Current McPAT assumes single DIMMs are used.-->
+ <param name="number_ranks" value="2"/>
+ <param name="num_banks_of_DRAM_chip" value="6"/>
+ <param name="Block_width_of_DRAM_chip" value="64"/> <!-- B -->
+ <param name="output_width_of_DRAM_chip" value="8"/>
+ <!--number of Dram_chips_per_rank=" 72/output_width_of_DRAM_chip-->
+ <!--number of Dram_chips_per_rank=" 72/output_width_of_DRAM_chip-->
+ <param name="page_size_of_DRAM_chip" value="8"/> <!-- 8 or 16 -->
+ <param name="burstlength_of_DRAM_chip" value="8"/>
+ <stat name="memory_accesses" value="1052"/>
+ <stat name="memory_reads" value="1052"/>
+ <stat name="memory_writes" value="1052"/>
+ </component>
+ <component id="system.mc" name="mc">
+ <!-- Memeory controllers are for DDR(2,3...) DIMMs -->
+ <!-- current version of McPAT uses published values for base parameters of memory controller
+ improvments on MC will be added in later versions. -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="mc_clock" value="1848"/><!--DIMM IO bus clock rate MHz DDR2-400 for Niagara 1-->
+ <param name="peak_transfer_rate" value="29568"/><!--MB/S Syed: GTX 470 has 177.4GB/s mem transfer rate with 6 MCs -->
+ <param name="block_size" value="64"/><!--B-->
+ <param name="number_mcs" value="6"/><!-- 6 GDDR5 memory controllers -->
+ <!-- current McPAT only supports homogeneous memory controllers -->
+ <param name="memory_channels_per_mc" value="2"/>
+ <param name="number_ranks" value="1"/>
+ <param name="withPHY" value="0"/>
+ <!-- # of ranks of each channel-->
+ <param name="req_window_size_per_channel" value="16"/>
+ <param name="IO_buffer_size_per_channel" value="16"/>
+ <param name="databus_width" value="32"/>
+ <param name="addressbus_width" value="32"/>
+ <param name="PRT_entries" value="32"/>
+ <!-- # of empirical DRAM model parameter -->
+ <param name="dram_cmd_coeff" value="0"/>
+ <param name="dram_act_coeff" value="0"/>
+ <param name="dram_nop_coeff" value="0"/>
+ <param name="dram_activity_coeff" value="0"/>
+ <param name="dram_pre_coeff" value="3.8475e-8f"/>
+ <param name="dram_rd_coeff" value="7.74707143e-8f"/>
+ <param name="dram_wr_coeff" value="3.54664286e-8f"/>
+ <param name="dram_req_coeff" value="0"/>
+ <param name="dram_const_coeff" value="0"/>
+
+ <!-- McPAT will add the control bus width to the addressbus width automatically -->
+ <stat name="memory_accesses" value="memory_accesses_match_mcpat"/>
+ <stat name="memory_reads" value="memory_reads_match_mcpat"/>
+ <stat name="memory_writes" value="memory_writes_match_mcpat"/>
+ <!-- McPAT does not track individual mc, instead, it takes the total accesses and calculate
+ the average power per MC or per channel. This is sufficent for most application.
+ Further trackdown can be easily added in later versions. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.niu" name="niu">
+ <!-- On chip 10Gb Ethernet NIC, including XAUI Phy and MAC controller -->
+ <!-- For a minimum IP packet size of 84B at 10Gb/s, a new packet arrives every 67.2ns.
+ the low bound of clock rate of a 10Gb MAC is 150Mhz -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="clockrate" value="350"/>
+ <param name="number_units" value="0"/> <!-- unlike PCIe and memory controllers, each Ethernet controller only have one port -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- ratio of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual nic, instead, it takes the total accesses and calculate
+ the average power per nic or per channel. This is sufficent for most application. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.pcie" name="pcie">
+ <!-- On chip PCIe controller, including Phy-->
+ <!-- For a minimum PCIe packet size of 84B at 8Gb/s per lane (PCIe 3.0), a new packet arrives every 84ns.
+ the low bound of clock rate of a PCIe per lane logic is 120Mhz -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="withPHY" value="1"/>
+ <param name="clockrate" value="350"/>
+ <param name="number_units" value="0"/>
+ <param name="num_channels" value="8"/> <!-- 2 ,4 ,8 ,16 ,32 -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- Percentage of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual pcie controllers, instead, it takes the total accesses and calculate
+ the average power per pcie controller or per channel. This is sufficent for most application. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.flashc" name="flashc">
+ <param name="number_flashcs" value="0"/>
+ <param name="type" value="1"/> <!-- 1: low power; 0 high performance -->
+ <param name="withPHY" value="1"/>
+ <param name="peak_transfer_rate" value="200"/><!--Per controller sustainable reak rate MB/S -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- Percentage of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual flash controller, instead, it takes the total accesses and calculate
+ the average power per fc or per channel. This is sufficent for most application -->
+ </component>
+<!--**********************************************************************-->
+
+ </component>
+</component>
\ No newline at end of file diff --git a/configs/tested-cfgs/SM7_GV100/accelwattch_sass_hw.xml b/configs/tested-cfgs/SM7_GV100/accelwattch_sass_hw.xml new file mode 100644 index 0000000..64f89d6 --- /dev/null +++ b/configs/tested-cfgs/SM7_GV100/accelwattch_sass_hw.xml @@ -0,0 +1,613 @@ +<?xml version="1.0" ?>
+<component id="root" name="root">
+ <component id="system" name="system">
+<!-- Copyright (c) 2018-2021, Vijay Kandiah, Junrui Pan, Mahmoud Khairy, Scott Peverelle, Timothy Rogers, Tor M. Aamodt, Nikos Hardavellas
+Northwestern University, Purdue University, The University of British Columbia
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer;
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution;
+3. Neither the names of Northwestern University, Purdue University,
+ The University of British Columbia nor the names of their contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE. -->
+
+ <!-- DYNAMIC Power Activity Factors -->
+
+ <param name="TOT_INST" value="100" /> <!--Instruction Buffer Activity Factor(Total Warp Instructions)-->
+ <param name="FP_INT" value="43.5416637" /> <!--Scheduler Activity Factor(Non-Memory Warp Instructons)-->
+ <param name="IC_H" value="0" /> <!--Instruction Cache Hits -->
+ <param name="IC_M" value="0" /> <!--Instruction Cache Misses-->
+ <param name="DC_RH" value="7.193244877" /> <!--L1 Data Cache Read Hits-->
+ <param name="DC_RM" value="8.01198819" /> <!--L1 Data Cache Read Misses-->
+ <param name="DC_WH" value="0.497094158" /> <!--L1 Data Cache Write Hits-->
+ <param name="DC_WM" value="12.9276971" /> <!--L1 Data Cache Write Misses-->
+ <param name="CC_H" value="9.322047" /> <!--Constant Cache Hits-->
+ <param name="CC_M" value="10.383093" /> <!--Constant Cache Misses-->
+ <param name="SHRD_ACC" value="4.146674883" /> <!--Shared Memory Accesses-->
+ <param name="REG_RD" value="0" /> <!--Register Reads-->
+ <param name="REG_WR" value="0" /> <!--Register Writes-->
+ <param name="INT_ACC" value="3.350646078" /> <!--Integer ALU Accesses-->
+ <param name="FP_ACC" value="0.041043127" /> <!--FPU Accesses-->
+ <param name="DP_ACC" value="0.077722905" /> <!--Integer Accesses-->
+ <param name="INT_MUL_ACC" value="0.147866461" /> <!--Integer MUL Accesses-->
+ <param name="FP_MUL_ACC" value="0.147864271" /> <!--FP MUL Accesses-->
+ <param name="FP_SQRT_ACC" value="0.48526506" /> <!--SFU: sqrt Accesses-->
+ <param name="FP_LG_ACC" value="0.147864519" /> <!--SFU: log Accesses-->
+ <param name="FP_SIN_ACC" value="0.376510619" /> <!--SFU: sin/cos Accesses-->
+ <param name="FP_EXP_ACC" value="0.147862451" /> <!--SFU: exponent Accesses-->
+ <param name="DP_MUL_ACC" value="0.147865348" /> <!--DP MUL Accesses-->
+ <param name="TENSOR_ACC" value="0.148632914" /> <!--Tensor Accesses-->
+ <param name="TEX_ACC" value="3.4530026" /> <!--Texture Unit Accesses-->
+ <param name="MEM_RD" value="0.020752854" /> <!--DRAM Reads-->
+ <param name="MEM_WR" value="0.025154975" /> <!--DRAM Writes-->
+ <param name="MEM_PRE" value="0.006917618" /> <!--DRAM Precharge-->
+ <param name="L2_RH" value="3.430442278" /> <!--L2 Data Cache Read Hits-->
+ <param name="L2_RM" value="6.514812193" /> <!--L2 Data Cache Read Misses-->
+ <param name="L2_WH" value="11.22265896" /> <!--L2 Data Cache Write Hits-->
+ <param name="L2_WM" value="3.32662057" /> <!--L2 Data Cache Write Misses-->
+ <param name="NOC_A" value="87.30828879" /> <!--Interconnect Network Accesses-->
+ <param name="PIPE_A" value="1.028" /> <!--Pipeline Accesses-->
+
+ <!-- STATIC & CONSTANT Power -->
+
+ <param name="constant_power" value="32.32522272" /> <!--Constant power-->
+ <param name="idle_core_power" value="0.28279166"/> <!--Idle SM power-->
+
+ <param name="static_cat1_flane" value="15.29035866"/> <!--INT (ADD+MUL) First Lane Activation Power-->
+ <param name="static_cat1_addlane" value="0.586233603"/> <!--INT (ADD+MUL) Additional Lane Activation Power-->
+
+ <param name="static_cat2_flane" value="18.6179906"/> <!--INT+FP First Lane Activation Power-->
+ <param name="static_cat2_addlane" value="0.645228013"/> <!--INT+FP Additional Lane Activation Power-->
+
+ <param name="static_cat3_flane" value="19.10017723"/> <!--INT+FP+DP First Lane Activation Power-->
+ <param name="static_cat3_addlane" value="0.726863055"/> <!--INT+FP+DP Additional Lane Activation Power-->
+
+ <param name="static_cat4_flane" value="18.55029744"/> <!--INT+FP+SFU First Lane Activation Power-->
+ <param name="static_cat4_addlane" value="0.6099397"/> <!--INT+FP+SFU Additional Lane Activation Power-->
+
+ <param name="static_cat5_flane" value="14.74826681"/> <!--INT+FP+TEX First Lane Activation Power-->
+ <param name="static_cat5_addlane" value="0.514367937"/> <!--INT+FP+TEX Additional Lane Activation Power-->
+
+ <param name="static_cat6_flane" value="48.94875596"/> <!--INT+FP+TENSOR First Lane Activation Power-->
+ <param name="static_cat6_addlane" value="0.0"/> <!--INT+FP+TENSOR Additional Lane Activation Power-->
+
+ <param name="static_light_flane" value="1.965373811"/> <!--LIGHT_SM First Lane Activation Power-->
+ <param name="static_light_addlane" value="0.003966868"/> <!--LIGHT_SM Additional Lane Activation Power-->
+
+ <param name="static_intadd_flane" value="19.70468506"/> <!--INT ADD First Lane Activation Power-->
+ <param name="static_intadd_addlane" value="0.388578623"/> <!--INT ADD Additional Lane Activation Power-->
+
+ <param name="static_intmul_flane" value="16.64811823"/> <!--INT MUL First Lane Activation Power-->
+ <param name="static_intmul_addlane" value="0.281803166"/> <!--INT MUL Additional Lane Activation Power-->
+
+ <param name="static_geomean_flane" value="17.21745077"/> <!--GEOMEAN First Lane Activation Power-->
+ <param name="static_geomean_addlane" value="0.650630555"/> <!--GEOMEAN Additional Lane Activation Power-->
+ <param name="static_shared_flane" value="31.40965691"/> <!--Shared Memory First Lane Activation Power-->
+ <param name="static_l1_flane" value="34.79491352"/> <!--L1D First Lane Activation Power-->
+ <param name="static_l2_flane" value="17.30654755"/> <!--L2D ADD+MUL First Lane Activation Power-->
+
+
+ <!-- LEAVE BELOW UNCHANGED! These are parameters used for initial GPUWattch model left untouched -->
+
+
+ <param name="GPU_Architecture" value="1"/><!-- 0-G80; 1-Fermi; others not supported -->
+ <param name="architecture" value="1"/> <!-- fermi:1 quadro:2 other: undefined-->
+ <param name="number_of_L1Directories" value="0"/>
+ <param name="number_of_L2Directories" value="0"/>
+ <param name="number_of_L2s" value="1"/> <!-- This number means how many L2 clusters in each cluster there can be multiple banks/ports -->
+ <param name="number_of_L3s" value="0"/> <!-- This number means how many L3 clusters -->
+ <param name="number_of_NoCs" value="1"/>
+ <param name="homogeneous_cores" value="1"/><!--1 means homo -->
+ <param name="homogeneous_L2s" value="1"/>
+ <param name="homogeneous_L1Directorys" value="1"/>
+ <param name="homogeneous_L2Directorys" value="1"/>
+ <param name="homogeneous_L3s" value="1"/>
+ <param name="homogeneous_ccs" value="1"/><!--cache coherece hardware -->
+ <param name="homogeneous_NoCs" value="1"/>
+ <param name="core_tech_node" value="23"/><!-- nm -->
+
+ <param name="number_cache_levels" value="2"/>
+ <param name="interconnect_projection_type" value="0"/><!--0: agressive wire technology; 1: conservative wire technology -->
+ <param name="device_type" value="0"/><!--0: HP(High Performance Type); 1: LSTP(Low standby power) 2: LOP (Low Operating Power) -->
+ <param name="longer_channel_device" value="1"/><!-- 0 no use; 1 use when possible -->
+ <param name="machine_bits" value="32"/>
+ <param name="virtual_address_width" value="32"/>
+ <param name="physical_address_width" value="32"/>
+ <param name="virtual_memory_page_size" value="4096"/>
+
+ <param name="IDLE_CORE_N" value="1"/>
+ <stat name="num_idle_cores" value="0"/><!-- Average Number of idle cores during this period -->
+ <stat name="total_cycles" value="total_cycles_match_mcpat"/>
+ <stat name="idle_cycles" value="idle_cycles_match_mcpat"/>
+ <stat name="busy_cycles" value="busy_cycles_match_mcpat"/>
+ <!--This page size(B) is complete different from the page size in Main memo secction. this page size is the size of
+ virtual memory from OS/Archi perspective; the page size in Main memo secction is the actuall physical line in a DRAM bank -->
+ <!-- *********************** cores ******************* -->
+ <component id="system.core0" name="core0">
+ <!-- Core property -->
+ <param name="clock_rate" value="700"/>
+ <param name="instruction_length" value="32"/>
+ <param name="opcode_width" value="9"/>
+ <!-- address width determins the tag_width in Cache, LSQ and buffers in cache controller
+ default value is machine_bits, if not set -->
+ <param name="machine_type" value="1"/><!-- 1 inorder; 0 OOO-->
+ <!-- inorder/OoO -->
+ <param name="number_hardware_threads" value="32"/>
+ <!-- number_instruction_fetch_ports(icache ports) is always 1 in single-thread processor,
+ it only may be more than one in SMT processors. BTB ports always equals to fetch ports since
+ branch information in consective branch instructions in the same fetch group can be read out from BTB once.-->
+ <param name="fetch_width" value="1"/>
+ <!-- fetch_width determins the size of cachelines of L1 cache block -->
+ <param name="number_instruction_fetch_ports" value="1"/>
+ <param name="decode_width" value="1"/>
+ <!-- decode_width determins the number of ports of the
+ renaming table (both RAM and CAM) scheme -->
+ <param name="issue_width" value="2"/>
+ <!-- issue_width determins the number of ports of Issue window and other logic
+ as in the complexity effective proccessors paper; issue_width==dispatch_width -->
+ <param name="commit_width" value="2"/>
+ <!-- commit_width determins the number of ports of register files -->
+ <param name="fp_issue_width" value="1"/>
+ <param name="prediction_width" value="0"/>
+ <!-- number of branch instructions can be predicted simultannouesl-->
+ <!-- Current version of McPAT does not distinguish int and floating point pipelines
+ Theses parameters are reserved for future use.-->
+ <param name="pipelines_per_core" value="1,1"/>
+ <!--integer_pipeline and floating_pipelines, if the floating_pipelines is 0, then the pipeline is shared-->
+ <param name="pipeline_depth" value="8,8"/>
+ <!-- pipeline depth of int and fp, if pipeline is shared, the second number is the average cycles of fp ops -->
+ <!-- issue and exe unit-->
+ <param name="ALU_per_core" value="32"/>
+ <!-- contains an adder, a shifter, and a logical unit -->
+ <param name="MUL_per_core" value="4"/>
+ <!-- For MUL and Div -->
+ <param name="FPU_per_core" value="32"/>
+ <!-- buffer between IF and ID stage -->
+ <param name="instruction_buffer_size" value="1"/>
+ <!-- buffer between ID and sche/exe stage -->
+ <param name="decoded_stream_buffer_size" value="1"/>
+ <param name="instruction_window_scheme" value="0"/><!-- 0 PHYREG based, 1 RSBASED-->
+ <!-- McPAT support 2 types of OoO cores, RS based and physical reg based-->
+ <param name="instruction_window_size" value="1"/>
+ <param name="fp_instruction_window_size" value="1"/>
+ <!-- the instruction issue Q as in Alpha 21264; The RS as in Intel P6 -->
+ <param name="ROB_size" value="0"/>
+ <!-- each in-flight instruction has an entry in ROB -->
+ <!-- registers -->
+ <!-- SM parameters Added by Syed Gilani -->
+ <param name="rf_banks" value="32"/>
+ <param name="simd_width" value="32"/>
+ <param name="collector_units" value="32"/>
+ <param name="core_clock_ratio" value="2"/>
+ <param name="warp_size" value="32"/>
+
+ <param name="archi_Regs_IRF_size" value="65536"/>
+ <param name="archi_Regs_FRF_size" value="32"/>
+ <!-- if OoO processor, phy_reg number is needed for renaming logic,
+ renaming logic is for both integer and floating point insts. -->
+ <param name="phy_Regs_IRF_size" value="32"/>
+ <param name="phy_Regs_FRF_size" value="32"/>
+ <!-- rename logic -->
+ <param name="rename_scheme" value="0"/>
+ <!-- can be RAM based(0) or CAM based(1) rename scheme
+ RAM-based scheme will have free list, status table;
+ CAM-based scheme have the valid bit in the data field of the CAM
+ both RAM and CAM need RAM-based checkpoint table, checkpoint_depth=# of in_flight instructions;
+ Detailed RAT Implementation see TR -->
+ <param name="register_windows_size" value="0"/>
+ <!-- how many windows in the windowed register file, sun processors;
+ no register windowing is used when this number is 0 -->
+ <!-- In OoO cores, loads and stores can be issued whether inorder(Pentium Pro) or (OoO)out-of-order(Alpha),
+ They will always try to exeute out-of-order though. -->
+ <param name="LSU_order" value="inorder"/>
+ <param name="store_buffer_size" value="32"/>
+ <!-- By default, in-order cores do not have load buffers -->
+ <param name="load_buffer_size" value="32"/>
+ <!-- number of ports refer to sustainable concurrent memory accesses -->
+ <param name="memory_ports" value="2"/>
+ <!-- max_allowed_in_flight_memo_instructions determins the # of ports of load and store buffer
+ as well as the ports of Dcache which is connected to LSU -->
+ <!-- dual-pumped Dcache can be used to save the extra read/write ports -->
+ <param name="RAS_size" value="1"/>
+ <!-- general stats, defines simulation periods;require total, idle, and busy cycles for senity check -->
+ <!-- please note: if target architecture is X86, then all the instrucions refer to (fused) micro-ops -->
+ <stat name="total_instructions" value="total_instructions_match_mcpat"/>
+ <stat name="int_instructions" value="int_instruction_match_mcpat"/>
+ <stat name="fp_instructions" value="flt_instruction_match_mcpat"/>
+ <stat name="branch_instructions" value="branch_instruction_match_mcpat"/>
+ <stat name="branch_mispredictions" value="0"/>
+ <stat name="load_instructions" value="load_instruction_match_mcpat"/>
+ <stat name="store_instructions" value="store_instruction_match_mcpat"/>
+ <stat name="committed_instructions" value="total_instructions_match_mcpat"/>
+ <stat name="committed_int_instructions" value="int_instruction_match_mcpat"/>
+ <stat name="committed_fp_instructions" value="flt_instruction_match_mcpat"/>
+ <stat name="pipeline_duty_cycle" value="0.6"/><!--<=1, runtime_ipc/peak_ipc; averaged for all cores if homogenous -->
+ <!-- the following cycle stats are used for heterogeneouse cores only,
+ please ignore them if homogeneouse cores -->
+ <stat name="total_cycles" value="total_cycles_match_mcpat"/>
+ <stat name="idle_cycles" value="idle_cycles_match_mcpat"/>
+ <stat name="busy_cycles" value="busy_cycles_match_mcpat"/>
+ <!-- instruction buffer stats -->
+ <!-- ROB stats, both RS and Phy based OoOs have ROB
+ performance simulator should capture the difference on accesses,
+ otherwise, McPAT has to guess based on number of commited instructions. -->
+ <stat name="ROB_reads" value="263886"/>
+ <stat name="ROB_writes" value="263886"/>
+ <!-- RAT accesses -->
+ <stat name="rename_accesses" value="263886"/>
+ <stat name="fp_rename_accesses" value="263886"/>
+ <!-- decode and rename stage use this, should be total ic - nop -->
+ <!-- Inst window stats -->
+ <stat name="inst_window_reads" value="263886"/>
+ <stat name="inst_window_writes" value="263886"/>
+ <stat name="inst_window_wakeup_accesses" value="263886"/>
+ <stat name="fp_inst_window_reads" value="263886"/>
+ <stat name="fp_inst_window_writes" value="263886"/>
+ <stat name="fp_inst_window_wakeup_accesses" value="263886"/>
+ <!-- RF accesses -->
+ <stat name="int_regfile_reads" value="int_register_read_access_match_mcpat"/>
+ <stat name="float_regfile_reads" value="int_register_write_access_match_mcpat"/>
+ <stat name="int_regfile_writes" value="float_register_read_access_match_mcpat"/>
+ <stat name="float_regfile_writes" value="float_register_write_access_match_mcpat"/>
+
+ <!-- The following stat is for operand collector power - Added by Syed -->
+ <stat name="non_rf_operands" value="0"/>
+
+ <!-- accesses to the working reg -->
+ <stat name="function_calls" value="0"/>
+ <stat name="context_switches" value="0"/> <!--not used in the McPAT -->
+ <!-- Number of Windowes switches (number of function calls and returns)-->
+ <!-- Alu stats by default, the processor has one FPU that includes the divider and
+ multiplier. The fpu accesses should include accesses to multiplier and divider -->
+ <stat name="ialu_accesses" value="ialu_accesses_match_mcpat"/>
+ <stat name="fpu_accesses" value="fpu_accesses_match_mcpat"/>
+ <stat name="mul_accesses" value="mul_accesses_match_mcpat"/>
+ <stat name="cdb_alu_accesses" value="0"/>
+ <stat name="cdb_mul_accesses" value="0"/>
+ <stat name="cdb_fpu_accesses" value="0"/>
+ <!-- multiple cycle accesses should be counted multiple times,
+ otherwise, McPAT can use internal counter for different floating point instructions
+ to get final accesses. But that needs detailed info for floating point inst mix -->
+ <!-- currently the performance simulator should
+ make sure all the numbers are final numbers,
+ including the explicit read/write accesses,
+ and the implicite accesses such as replacements and etc.
+ Future versions of McPAT may be able to reason the implicite access
+ based on param and stats of last level cache
+ The same rule applies to all cache access stats too! -->
+ <!-- following is AF for max power computation.
+ Do not change them, unless you understand them-->
+ <stat name="IFU_duty_cycle" value="0.25"/>
+ <stat name="LSU_duty_cycle" value="0.25"/>
+ <stat name="MemManU_I_duty_cycle" value="1"/>
+ <stat name="MemManU_D_duty_cycle" value="0.25"/>
+ <stat name="ALU_duty_cycle" value="0.9"/>
+ <stat name="MUL_duty_cycle" value="0.5"/>
+ <stat name="FPU_duty_cycle" value="1"/><!-- FPU numbers are already average -->
+ <stat name="ALU_cdb_duty_cycle" value="0.9"/>
+ <stat name="MUL_cdb_duty_cycle" value="0.5"/>
+ <stat name="FPU_cdb_duty_cycle" value="15"/>
+ <component id="system.core0.predictor" name="PBT">
+ <!-- branch predictor; tournament predictor see Alpha implementation -->
+ <param name="local_predictor_size" value="10,3"/>
+ <param name="local_predictor_entries" value="1024"/>
+ <param name="global_predictor_entries" value="4096"/>
+ <param name="global_predictor_bits" value="2"/>
+ <param name="chooser_predictor_entries" value="4096"/>
+ <param name="chooser_predictor_bits" value="2"/>
+ <!-- These parameters can be combined like below in next version
+ <param name="load_predictor" value="10,3,1024"/>
+ <param name="global_predictor" value="4096,2"/>
+ <param name="predictor_chooser" value="4096,2"/>
+ -->
+ </component>
+ <component id="system.core0.itlb" name="itlb">
+ <param name="number_entries" value="1"/>
+ <stat name="total_accesses" value="0"/>
+ <stat name="total_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <!-- there is no write requests to itlb although writes happen to itlb after miss,
+ which is actually a replacement -->
+ </component>
+ <component id="system.core0.icache" name="icache">
+ <!-- there is no write requests to itlb although writes happen to it after miss,
+ which is actually a replacement -->
+ <param name="icache_config" value="16384,128,4,1,1,3,8,0"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <!-- cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate -->
+ <param name="buffer_sizes" value="16, 16, 16,0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="total_instructions_match_mcpat"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.dtlb" name="dtlb">
+ <param name="number_entries" value="1"/>
+ <stat name="total_accesses" value="0"/>
+ <stat name="total_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.ccache" name="ccache">
+ <!-- all the buffer related are optional -->
+ <param name="ccache_config" value="16384,64,2,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="ccache_read_accesses_match_mcpat"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="ccache_read_misses_match_mcpat"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.tcache" name="tcache">
+ <!-- all the buffer related are optional -->
+ <param name="tcache_config" value="49152,128,8,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="tcache_read_accesses_match_mcpat"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="tcache_read_misses_match_mcpat"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <!--model the shared memory by mimicing dcache-->
+ <component id="system.core0.sharedmemory" name="sharedmemory">
+ <!-- all the buffer related are optional -->
+ <param name="sharedmemory_config" value="98304,16,1,16,1,3,16,0"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="sharedmemory_read_access_match_mcpat"/>
+ <stat name="write_accesses" value="sharedmemory_write_access_match_mcpat"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.dcache" name="dcache">
+ <!-- all the buffer related are optional -->
+ <param name="dcache_config" value="16384,32,4,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="dcache_read_access_match_mcpat"/>
+ <stat name="write_accesses" value="dcache_write_access_match_mcpat"/>
+ <stat name="read_misses" value="dcache_read_miss_match_mcpat"/>
+ <stat name="write_misses" value="dcache_write_miss_match_mcpat"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.BTB" name="BTB">
+ <!-- all the buffer related are optional -->
+ <param name="BTB_config" value="8192,4,2,1, 1,3"/>
+ <!-- the parameters are capacity,block_width,associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ </component>
+ </component>
+ <component id="system.L1Directory0" name="L1Directory0">
+ <param name="Directory_type" value="0"/>
+ <!--0 cam based shadowed tag. 1 directory cache -->
+ <param name="Dir_config" value="2048,1,0,1, 4, 4,8"/>
+ <!-- the parameters are capacity,block_width, associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ <param name="buffer_sizes" value="8, 8, 8, 8"/>
+ <!-- all the buffer related are optional -->
+ <param name="clockrate" value="1400"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw search ports -->
+ <param name="device_type" value="0"/>
+ <!-- altough there are multiple access types,
+ Performance simulator needs to cast them into reads or writes
+ e.g. the invalidates can be considered as writes -->
+ <stat name="read_accesses" value="800000"/>
+ <stat name="write_accesses" value="27276"/>
+ <stat name="read_misses" value="1632"/>
+ <stat name="write_misses" value="183"/>
+ <stat name="conflicts" value="20"/>
+ <stat name="duty_cycle" value="0.45"/>
+ </component>
+ <component id="system.L2Directory0" name="L2Directory0">
+ <param name="Directory_type" value="1"/>
+ <!--0 cam based shadowed tag. 1 directory cache -->
+ <param name="Dir_config" value="1048576,16,16,1,2, 100"/>
+ <!-- the parameters are capacity,block_width, associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ <param name="buffer_sizes" value="8, 8, 8, 8"/>
+ <!-- all the buffer related are optional -->
+ <param name="clockrate" value="1400"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw search ports -->
+ <param name="device_type" value="0"/>
+ <!-- altough there are multiple access types,
+ Performance simulator needs to cast them into reads or writes
+ e.g. the invalidates can be considered as writes -->
+ <stat name="read_accesses" value="0"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.45"/>
+ </component>
+ <component id="system.L20" name="L20">
+ <!-- all the buffer related are optional -->
+ <param name="L2_config" value="131072,128,16,1, 4,23, 64, 1"/>
+ <!-- consider 4-way bank interleaving for Niagara 1 -->
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <param name="clockrate" value="2962"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw ports -->
+ <param name="device_type" value="0"/>
+ <stat name="read_accesses" value="200000"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.5"/>
+ </component>
+
+<!--**********************************************************************-->
+<component id="system.L30" name="L30">
+ <param name="L3_config" value="1048576,64,16,1, 2,100, 64,1"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="clockrate" value="3500"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw ports -->
+ <param name="device_type" value="0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="58824"/>
+ <stat name="write_accesses" value="27276"/>
+ <stat name="read_misses" value="1632"/>
+ <stat name="write_misses" value="183"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.35"/>
+ </component>
+
+
+<!--**********************************************************************-->
+ <component id="system.NoC0" name="noc0">
+ <param name="clockrate" value="700"/>
+ <param name="type" value="1"/>
+ <!-- 1 NoC, O bus -->
+ <param name="horizontal_nodes" value="2"/>
+ <param name="vertical_nodes" value="1"/>
+ <param name="has_global_link" value="0"/>
+ <!-- 1 has global link, 0 does not have global link -->
+ <param name="link_throughput" value="1"/><!--w.r.t clock -->
+ <param name="link_latency" value="1"/><!--w.r.t clock -->
+ <!-- througput >= latency -->
+ <!-- Router architecture -->
+ <param name="input_ports" value="6"/>
+ <param name="output_ports" value="6"/>
+ <param name="virtual_channel_per_port" value="1"/>
+ <!-- input buffer; in classic routers only input ports need buffers -->
+ <param name="flit_bits" value="32"/>
+ <param name="input_buffer_entries_per_vc" value="1"/><!--VCs within the same ports share input buffers whose size is propotional to the number of VCs-->
+ <param name="chip_coverage" value="1"/>
+ <!-- When multiple NOC present, one NOC will cover part of the whole chip. chip_coverage <=1 -->
+ <stat name="total_accesses" value="0"/>
+ <!-- This is the number of total accesses within the whole network not for each router -->
+ <stat name="duty_cycle" value="0.6"/>
+ </component>
+<!--**********************************************************************-->
+<!--**********************************************************************-->
+
+ <component id="system.mem" name="mem">
+ <!-- Main memory property -->
+ <param name="mem_tech_node" value="23"/>
+ <param name="device_clock" value="200"/><!--MHz, this is clock rate of the actual memory device, not the FSB -->
+ <param name="peak_transfer_rate" value="3200"/><!--MB/S-->
+ <param name="internal_prefetch_of_DRAM_chip" value="4"/>
+ <!-- 2 for DDR, 4 for DDR2, 8 for DDR3...-->
+ <!-- the device clock, peak_transfer_rate, and the internal prefetch decide the DIMM property -->
+ <!-- above numbers can be easily found from Wikipedia -->
+ <param name="capacity_per_channel" value="4096"/> <!-- MB -->
+ <!-- capacity_per_Dram_chip=capacity_per_channel/number_of_dimms/number_ranks/Dram_chips_per_rank
+ Current McPAT assumes single DIMMs are used.-->
+ <param name="number_ranks" value="2"/>
+ <param name="num_banks_of_DRAM_chip" value="6"/>
+ <param name="Block_width_of_DRAM_chip" value="64"/> <!-- B -->
+ <param name="output_width_of_DRAM_chip" value="8"/>
+ <!--number of Dram_chips_per_rank=" 72/output_width_of_DRAM_chip-->
+ <!--number of Dram_chips_per_rank=" 72/output_width_of_DRAM_chip-->
+ <param name="page_size_of_DRAM_chip" value="8"/> <!-- 8 or 16 -->
+ <param name="burstlength_of_DRAM_chip" value="8"/>
+ <stat name="memory_accesses" value="1052"/>
+ <stat name="memory_reads" value="1052"/>
+ <stat name="memory_writes" value="1052"/>
+ </component>
+ <component id="system.mc" name="mc">
+ <!-- Memeory controllers are for DDR(2,3...) DIMMs -->
+ <!-- current version of McPAT uses published values for base parameters of memory controller
+ improvments on MC will be added in later versions. -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="mc_clock" value="1848"/><!--DIMM IO bus clock rate MHz DDR2-400 for Niagara 1-->
+ <param name="peak_transfer_rate" value="29568"/><!--MB/S Syed: GTX 470 has 177.4GB/s mem transfer rate with 6 MCs -->
+ <param name="block_size" value="64"/><!--B-->
+ <param name="number_mcs" value="6"/><!-- 6 GDDR5 memory controllers -->
+ <!-- current McPAT only supports homogeneous memory controllers -->
+ <param name="memory_channels_per_mc" value="2"/>
+ <param name="number_ranks" value="1"/>
+ <param name="withPHY" value="0"/>
+ <!-- # of ranks of each channel-->
+ <param name="req_window_size_per_channel" value="16"/>
+ <param name="IO_buffer_size_per_channel" value="16"/>
+ <param name="databus_width" value="32"/>
+ <param name="addressbus_width" value="32"/>
+ <param name="PRT_entries" value="32"/>
+ <!-- # of empirical DRAM model parameter -->
+ <param name="dram_cmd_coeff" value="0"/>
+ <param name="dram_act_coeff" value="0"/>
+ <param name="dram_nop_coeff" value="0"/>
+ <param name="dram_activity_coeff" value="0"/>
+ <param name="dram_pre_coeff" value="3.8475e-8f"/>
+ <param name="dram_rd_coeff" value="7.74707143e-8f"/>
+ <param name="dram_wr_coeff" value="3.54664286e-8f"/>
+ <param name="dram_req_coeff" value="0"/>
+ <param name="dram_const_coeff" value="0"/>
+
+ <!-- McPAT will add the control bus width to the addressbus width automatically -->
+ <stat name="memory_accesses" value="memory_accesses_match_mcpat"/>
+ <stat name="memory_reads" value="memory_reads_match_mcpat"/>
+ <stat name="memory_writes" value="memory_writes_match_mcpat"/>
+ <!-- McPAT does not track individual mc, instead, it takes the total accesses and calculate
+ the average power per MC or per channel. This is sufficent for most application.
+ Further trackdown can be easily added in later versions. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.niu" name="niu">
+ <!-- On chip 10Gb Ethernet NIC, including XAUI Phy and MAC controller -->
+ <!-- For a minimum IP packet size of 84B at 10Gb/s, a new packet arrives every 67.2ns.
+ the low bound of clock rate of a 10Gb MAC is 150Mhz -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="clockrate" value="350"/>
+ <param name="number_units" value="0"/> <!-- unlike PCIe and memory controllers, each Ethernet controller only have one port -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- ratio of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual nic, instead, it takes the total accesses and calculate
+ the average power per nic or per channel. This is sufficent for most application. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.pcie" name="pcie">
+ <!-- On chip PCIe controller, including Phy-->
+ <!-- For a minimum PCIe packet size of 84B at 8Gb/s per lane (PCIe 3.0), a new packet arrives every 84ns.
+ the low bound of clock rate of a PCIe per lane logic is 120Mhz -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="withPHY" value="1"/>
+ <param name="clockrate" value="350"/>
+ <param name="number_units" value="0"/>
+ <param name="num_channels" value="8"/> <!-- 2 ,4 ,8 ,16 ,32 -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- Percentage of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual pcie controllers, instead, it takes the total accesses and calculate
+ the average power per pcie controller or per channel. This is sufficent for most application. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.flashc" name="flashc">
+ <param name="number_flashcs" value="0"/>
+ <param name="type" value="1"/> <!-- 1: low power; 0 high performance -->
+ <param name="withPHY" value="1"/>
+ <param name="peak_transfer_rate" value="200"/><!--Per controller sustainable reak rate MB/S -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- Percentage of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual flash controller, instead, it takes the total accesses and calculate
+ the average power per fc or per channel. This is sufficent for most application -->
+ </component>
+<!--**********************************************************************-->
+
+ </component>
+</component>
\ No newline at end of file diff --git a/configs/tested-cfgs/SM7_GV100/accelwattch_sass_hybrid.xml b/configs/tested-cfgs/SM7_GV100/accelwattch_sass_hybrid.xml new file mode 100644 index 0000000..175f1fd --- /dev/null +++ b/configs/tested-cfgs/SM7_GV100/accelwattch_sass_hybrid.xml @@ -0,0 +1,613 @@ +<?xml version="1.0" ?>
+<component id="root" name="root">
+ <component id="system" name="system">
+<!-- Copyright (c) 2018-2021, Vijay Kandiah, Junrui Pan, Mahmoud Khairy, Scott Peverelle, Timothy Rogers, Tor M. Aamodt, Nikos Hardavellas
+Northwestern University, Purdue University, The University of British Columbia
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer;
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution;
+3. Neither the names of Northwestern University, Purdue University,
+ The University of British Columbia nor the names of their contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE. -->
+
+ <!-- DYNAMIC Power Activity Factors -->
+
+ <param name="TOT_INST" value="100" /> <!--Instruction Buffer Activity Factor(Total Warp Instructions)-->
+ <param name="FP_INT" value="48.259994" /> <!--Scheduler Activity Factor(Non-Memory Warp Instructons)-->
+ <param name="IC_H" value="0" /> <!--Instruction Cache Hits -->
+ <param name="IC_M" value="0" /> <!--Instruction Cache Misses-->
+ <param name="DC_RH" value="6.607568654" /> <!--L1 Data Cache Read Hits-->
+ <param name="DC_RM" value="7.359649633" /> <!--L1 Data Cache Read Misses-->
+ <param name="DC_WH" value="0.456620598" /> <!--L1 Data Cache Write Hits-->
+ <param name="DC_WM" value="11.87512" /> <!--L1 Data Cache Write Misses-->
+ <param name="CC_H" value="5.932232271" /> <!--Constant Cache Hits-->
+ <param name="CC_M" value="6.607445701" /> <!--Constant Cache Misses-->
+ <param name="SHRD_ACC" value="5.116439734" /> <!--Shared Memory Accesses-->
+ <param name="REG_RD" value="0" /> <!--Register Reads-->
+ <param name="REG_WR" value="0" /> <!--Register Writes-->
+ <param name="INT_ACC" value="7.725550311" /> <!--Integer ALU Accesses-->
+ <param name="FP_ACC" value="0.201142468" /> <!--FPU Accesses-->
+ <param name="DP_ACC" value="0.201146878" /> <!--Integer Accesses-->
+ <param name="INT_MUL_ACC" value="0.130624774" /> <!--Integer MUL Accesses-->
+ <param name="FP_MUL_ACC" value="0.130623287" /> <!--FP MUL Accesses-->
+ <param name="FP_SQRT_ACC" value="0.195089274" /> <!--SFU: sqrt Accesses-->
+ <param name="FP_LG_ACC" value="0.130617842" /> <!--SFU: log Accesses-->
+ <param name="FP_SIN_ACC" value="0.202205086" /> <!--SFU: sin/cos Accesses-->
+ <param name="FP_EXP_ACC" value="0.130621909" /> <!--SFU: exponent Accesses-->
+ <param name="DP_MUL_ACC" value="0.130622532" /> <!--DP MUL Accesses-->
+ <param name="TENSOR_ACC" value="0.240811904" /> <!--Tensor Accesses-->
+ <param name="TEX_ACC" value="3.453002628" /> <!--Texture Unit Accesses-->
+ <param name="MEM_RD" value="0.01527021" /> <!--DRAM Reads-->
+ <param name="MEM_WR" value="0.018509345" /> <!--DRAM Writes-->
+ <param name="MEM_PRE" value="0.00509007" /> <!--DRAM Precharge-->
+ <param name="L2_RH" value="3.391355385" /> <!--L2 Data Cache Read Hits-->
+ <param name="L2_RM" value="6.440581599" /> <!--L2 Data Cache Read Misses-->
+ <param name="L2_WH" value="11.09478657" /> <!--L2 Data Cache Write Hits-->
+ <param name="L2_WM" value="3.288716634" /> <!--L2 Data Cache Write Misses-->
+ <param name="NOC_A" value="86.3134871" /> <!--Interconnect Network Accesses-->
+ <param name="PIPE_A" value="0.514" /> <!--Pipeline Accesses-->
+
+ <!-- STATIC & CONSTANT Power -->
+
+ <param name="constant_power" value="32.32522272" /> <!--Constant power-->
+ <param name="idle_core_power" value="0.28279166"/> <!--Idle SM power-->
+
+ <param name="static_cat1_flane" value="15.29035866"/> <!--INT (ADD+MUL) First Lane Activation Power-->
+ <param name="static_cat1_addlane" value="0.586233603"/> <!--INT (ADD+MUL) Additional Lane Activation Power-->
+
+ <param name="static_cat2_flane" value="18.6179906"/> <!--INT+FP First Lane Activation Power-->
+ <param name="static_cat2_addlane" value="0.645228013"/> <!--INT+FP Additional Lane Activation Power-->
+
+ <param name="static_cat3_flane" value="19.10017723"/> <!--INT+FP+DP First Lane Activation Power-->
+ <param name="static_cat3_addlane" value="0.726863055"/> <!--INT+FP+DP Additional Lane Activation Power-->
+
+ <param name="static_cat4_flane" value="18.55029744"/> <!--INT+FP+SFU First Lane Activation Power-->
+ <param name="static_cat4_addlane" value="0.6099397"/> <!--INT+FP+SFU Additional Lane Activation Power-->
+
+ <param name="static_cat5_flane" value="14.74826681"/> <!--INT+FP+TEX First Lane Activation Power-->
+ <param name="static_cat5_addlane" value="0.514367937"/> <!--INT+FP+TEX Additional Lane Activation Power-->
+
+ <param name="static_cat6_flane" value="48.94875596"/> <!--INT+FP+TENSOR First Lane Activation Power-->
+ <param name="static_cat6_addlane" value="0.0"/> <!--INT+FP+TENSOR Additional Lane Activation Power-->
+
+ <param name="static_light_flane" value="1.965373811"/> <!--LIGHT_SM First Lane Activation Power-->
+ <param name="static_light_addlane" value="0.003966868"/> <!--LIGHT_SM Additional Lane Activation Power-->
+
+ <param name="static_intadd_flane" value="19.70468506"/> <!--INT ADD First Lane Activation Power-->
+ <param name="static_intadd_addlane" value="0.388578623"/> <!--INT ADD Additional Lane Activation Power-->
+
+ <param name="static_intmul_flane" value="16.64811823"/> <!--INT MUL First Lane Activation Power-->
+ <param name="static_intmul_addlane" value="0.281803166"/> <!--INT MUL Additional Lane Activation Power-->
+
+ <param name="static_geomean_flane" value="17.21745077"/> <!--GEOMEAN First Lane Activation Power-->
+ <param name="static_geomean_addlane" value="0.650630555"/> <!--GEOMEAN Additional Lane Activation Power-->
+ <param name="static_shared_flane" value="31.40965691"/> <!--Shared Memory First Lane Activation Power-->
+ <param name="static_l1_flane" value="34.79491352"/> <!--L1D First Lane Activation Power-->
+ <param name="static_l2_flane" value="17.30654755"/> <!--L2D ADD+MUL First Lane Activation Power-->
+
+
+ <!-- LEAVE BELOW UNCHANGED! These are parameters used for initial GPUWattch model left untouched -->
+
+
+ <param name="GPU_Architecture" value="1"/><!-- 0-G80; 1-Fermi; others not supported -->
+ <param name="architecture" value="1"/> <!-- fermi:1 quadro:2 other: undefined-->
+ <param name="number_of_L1Directories" value="0"/>
+ <param name="number_of_L2Directories" value="0"/>
+ <param name="number_of_L2s" value="1"/> <!-- This number means how many L2 clusters in each cluster there can be multiple banks/ports -->
+ <param name="number_of_L3s" value="0"/> <!-- This number means how many L3 clusters -->
+ <param name="number_of_NoCs" value="1"/>
+ <param name="homogeneous_cores" value="1"/><!--1 means homo -->
+ <param name="homogeneous_L2s" value="1"/>
+ <param name="homogeneous_L1Directorys" value="1"/>
+ <param name="homogeneous_L2Directorys" value="1"/>
+ <param name="homogeneous_L3s" value="1"/>
+ <param name="homogeneous_ccs" value="1"/><!--cache coherece hardware -->
+ <param name="homogeneous_NoCs" value="1"/>
+ <param name="core_tech_node" value="23"/><!-- nm -->
+
+ <param name="number_cache_levels" value="2"/>
+ <param name="interconnect_projection_type" value="0"/><!--0: agressive wire technology; 1: conservative wire technology -->
+ <param name="device_type" value="0"/><!--0: HP(High Performance Type); 1: LSTP(Low standby power) 2: LOP (Low Operating Power) -->
+ <param name="longer_channel_device" value="1"/><!-- 0 no use; 1 use when possible -->
+ <param name="machine_bits" value="32"/>
+ <param name="virtual_address_width" value="32"/>
+ <param name="physical_address_width" value="32"/>
+ <param name="virtual_memory_page_size" value="4096"/>
+
+ <param name="IDLE_CORE_N" value="1"/>
+ <stat name="num_idle_cores" value="0"/><!-- Average Number of idle cores during this period -->
+ <stat name="total_cycles" value="total_cycles_match_mcpat"/>
+ <stat name="idle_cycles" value="idle_cycles_match_mcpat"/>
+ <stat name="busy_cycles" value="busy_cycles_match_mcpat"/>
+ <!--This page size(B) is complete different from the page size in Main memo secction. this page size is the size of
+ virtual memory from OS/Archi perspective; the page size in Main memo secction is the actuall physical line in a DRAM bank -->
+ <!-- *********************** cores ******************* -->
+ <component id="system.core0" name="core0">
+ <!-- Core property -->
+ <param name="clock_rate" value="700"/>
+ <param name="instruction_length" value="32"/>
+ <param name="opcode_width" value="9"/>
+ <!-- address width determins the tag_width in Cache, LSQ and buffers in cache controller
+ default value is machine_bits, if not set -->
+ <param name="machine_type" value="1"/><!-- 1 inorder; 0 OOO-->
+ <!-- inorder/OoO -->
+ <param name="number_hardware_threads" value="32"/>
+ <!-- number_instruction_fetch_ports(icache ports) is always 1 in single-thread processor,
+ it only may be more than one in SMT processors. BTB ports always equals to fetch ports since
+ branch information in consective branch instructions in the same fetch group can be read out from BTB once.-->
+ <param name="fetch_width" value="1"/>
+ <!-- fetch_width determins the size of cachelines of L1 cache block -->
+ <param name="number_instruction_fetch_ports" value="1"/>
+ <param name="decode_width" value="1"/>
+ <!-- decode_width determins the number of ports of the
+ renaming table (both RAM and CAM) scheme -->
+ <param name="issue_width" value="2"/>
+ <!-- issue_width determins the number of ports of Issue window and other logic
+ as in the complexity effective proccessors paper; issue_width==dispatch_width -->
+ <param name="commit_width" value="2"/>
+ <!-- commit_width determins the number of ports of register files -->
+ <param name="fp_issue_width" value="1"/>
+ <param name="prediction_width" value="0"/>
+ <!-- number of branch instructions can be predicted simultannouesl-->
+ <!-- Current version of McPAT does not distinguish int and floating point pipelines
+ Theses parameters are reserved for future use.-->
+ <param name="pipelines_per_core" value="1,1"/>
+ <!--integer_pipeline and floating_pipelines, if the floating_pipelines is 0, then the pipeline is shared-->
+ <param name="pipeline_depth" value="8,8"/>
+ <!-- pipeline depth of int and fp, if pipeline is shared, the second number is the average cycles of fp ops -->
+ <!-- issue and exe unit-->
+ <param name="ALU_per_core" value="32"/>
+ <!-- contains an adder, a shifter, and a logical unit -->
+ <param name="MUL_per_core" value="4"/>
+ <!-- For MUL and Div -->
+ <param name="FPU_per_core" value="32"/>
+ <!-- buffer between IF and ID stage -->
+ <param name="instruction_buffer_size" value="1"/>
+ <!-- buffer between ID and sche/exe stage -->
+ <param name="decoded_stream_buffer_size" value="1"/>
+ <param name="instruction_window_scheme" value="0"/><!-- 0 PHYREG based, 1 RSBASED-->
+ <!-- McPAT support 2 types of OoO cores, RS based and physical reg based-->
+ <param name="instruction_window_size" value="1"/>
+ <param name="fp_instruction_window_size" value="1"/>
+ <!-- the instruction issue Q as in Alpha 21264; The RS as in Intel P6 -->
+ <param name="ROB_size" value="0"/>
+ <!-- each in-flight instruction has an entry in ROB -->
+ <!-- registers -->
+ <!-- SM parameters Added by Syed Gilani -->
+ <param name="rf_banks" value="32"/>
+ <param name="simd_width" value="32"/>
+ <param name="collector_units" value="32"/>
+ <param name="core_clock_ratio" value="2"/>
+ <param name="warp_size" value="32"/>
+
+ <param name="archi_Regs_IRF_size" value="65536"/>
+ <param name="archi_Regs_FRF_size" value="32"/>
+ <!-- if OoO processor, phy_reg number is needed for renaming logic,
+ renaming logic is for both integer and floating point insts. -->
+ <param name="phy_Regs_IRF_size" value="32"/>
+ <param name="phy_Regs_FRF_size" value="32"/>
+ <!-- rename logic -->
+ <param name="rename_scheme" value="0"/>
+ <!-- can be RAM based(0) or CAM based(1) rename scheme
+ RAM-based scheme will have free list, status table;
+ CAM-based scheme have the valid bit in the data field of the CAM
+ both RAM and CAM need RAM-based checkpoint table, checkpoint_depth=# of in_flight instructions;
+ Detailed RAT Implementation see TR -->
+ <param name="register_windows_size" value="0"/>
+ <!-- how many windows in the windowed register file, sun processors;
+ no register windowing is used when this number is 0 -->
+ <!-- In OoO cores, loads and stores can be issued whether inorder(Pentium Pro) or (OoO)out-of-order(Alpha),
+ They will always try to exeute out-of-order though. -->
+ <param name="LSU_order" value="inorder"/>
+ <param name="store_buffer_size" value="32"/>
+ <!-- By default, in-order cores do not have load buffers -->
+ <param name="load_buffer_size" value="32"/>
+ <!-- number of ports refer to sustainable concurrent memory accesses -->
+ <param name="memory_ports" value="2"/>
+ <!-- max_allowed_in_flight_memo_instructions determins the # of ports of load and store buffer
+ as well as the ports of Dcache which is connected to LSU -->
+ <!-- dual-pumped Dcache can be used to save the extra read/write ports -->
+ <param name="RAS_size" value="1"/>
+ <!-- general stats, defines simulation periods;require total, idle, and busy cycles for senity check -->
+ <!-- please note: if target architecture is X86, then all the instrucions refer to (fused) micro-ops -->
+ <stat name="total_instructions" value="total_instructions_match_mcpat"/>
+ <stat name="int_instructions" value="int_instruction_match_mcpat"/>
+ <stat name="fp_instructions" value="flt_instruction_match_mcpat"/>
+ <stat name="branch_instructions" value="branch_instruction_match_mcpat"/>
+ <stat name="branch_mispredictions" value="0"/>
+ <stat name="load_instructions" value="load_instruction_match_mcpat"/>
+ <stat name="store_instructions" value="store_instruction_match_mcpat"/>
+ <stat name="committed_instructions" value="total_instructions_match_mcpat"/>
+ <stat name="committed_int_instructions" value="int_instruction_match_mcpat"/>
+ <stat name="committed_fp_instructions" value="flt_instruction_match_mcpat"/>
+ <stat name="pipeline_duty_cycle" value="0.6"/><!--<=1, runtime_ipc/peak_ipc; averaged for all cores if homogenous -->
+ <!-- the following cycle stats are used for heterogeneouse cores only,
+ please ignore them if homogeneouse cores -->
+ <stat name="total_cycles" value="total_cycles_match_mcpat"/>
+ <stat name="idle_cycles" value="idle_cycles_match_mcpat"/>
+ <stat name="busy_cycles" value="busy_cycles_match_mcpat"/>
+ <!-- instruction buffer stats -->
+ <!-- ROB stats, both RS and Phy based OoOs have ROB
+ performance simulator should capture the difference on accesses,
+ otherwise, McPAT has to guess based on number of commited instructions. -->
+ <stat name="ROB_reads" value="263886"/>
+ <stat name="ROB_writes" value="263886"/>
+ <!-- RAT accesses -->
+ <stat name="rename_accesses" value="263886"/>
+ <stat name="fp_rename_accesses" value="263886"/>
+ <!-- decode and rename stage use this, should be total ic - nop -->
+ <!-- Inst window stats -->
+ <stat name="inst_window_reads" value="263886"/>
+ <stat name="inst_window_writes" value="263886"/>
+ <stat name="inst_window_wakeup_accesses" value="263886"/>
+ <stat name="fp_inst_window_reads" value="263886"/>
+ <stat name="fp_inst_window_writes" value="263886"/>
+ <stat name="fp_inst_window_wakeup_accesses" value="263886"/>
+ <!-- RF accesses -->
+ <stat name="int_regfile_reads" value="int_register_read_access_match_mcpat"/>
+ <stat name="float_regfile_reads" value="int_register_write_access_match_mcpat"/>
+ <stat name="int_regfile_writes" value="float_register_read_access_match_mcpat"/>
+ <stat name="float_regfile_writes" value="float_register_write_access_match_mcpat"/>
+
+ <!-- The following stat is for operand collector power - Added by Syed -->
+ <stat name="non_rf_operands" value="0"/>
+
+ <!-- accesses to the working reg -->
+ <stat name="function_calls" value="0"/>
+ <stat name="context_switches" value="0"/> <!--not used in the McPAT -->
+ <!-- Number of Windowes switches (number of function calls and returns)-->
+ <!-- Alu stats by default, the processor has one FPU that includes the divider and
+ multiplier. The fpu accesses should include accesses to multiplier and divider -->
+ <stat name="ialu_accesses" value="ialu_accesses_match_mcpat"/>
+ <stat name="fpu_accesses" value="fpu_accesses_match_mcpat"/>
+ <stat name="mul_accesses" value="mul_accesses_match_mcpat"/>
+ <stat name="cdb_alu_accesses" value="0"/>
+ <stat name="cdb_mul_accesses" value="0"/>
+ <stat name="cdb_fpu_accesses" value="0"/>
+ <!-- multiple cycle accesses should be counted multiple times,
+ otherwise, McPAT can use internal counter for different floating point instructions
+ to get final accesses. But that needs detailed info for floating point inst mix -->
+ <!-- currently the performance simulator should
+ make sure all the numbers are final numbers,
+ including the explicit read/write accesses,
+ and the implicite accesses such as replacements and etc.
+ Future versions of McPAT may be able to reason the implicite access
+ based on param and stats of last level cache
+ The same rule applies to all cache access stats too! -->
+ <!-- following is AF for max power computation.
+ Do not change them, unless you understand them-->
+ <stat name="IFU_duty_cycle" value="0.25"/>
+ <stat name="LSU_duty_cycle" value="0.25"/>
+ <stat name="MemManU_I_duty_cycle" value="1"/>
+ <stat name="MemManU_D_duty_cycle" value="0.25"/>
+ <stat name="ALU_duty_cycle" value="0.9"/>
+ <stat name="MUL_duty_cycle" value="0.5"/>
+ <stat name="FPU_duty_cycle" value="1"/><!-- FPU numbers are already average -->
+ <stat name="ALU_cdb_duty_cycle" value="0.9"/>
+ <stat name="MUL_cdb_duty_cycle" value="0.5"/>
+ <stat name="FPU_cdb_duty_cycle" value="15"/>
+ <component id="system.core0.predictor" name="PBT">
+ <!-- branch predictor; tournament predictor see Alpha implementation -->
+ <param name="local_predictor_size" value="10,3"/>
+ <param name="local_predictor_entries" value="1024"/>
+ <param name="global_predictor_entries" value="4096"/>
+ <param name="global_predictor_bits" value="2"/>
+ <param name="chooser_predictor_entries" value="4096"/>
+ <param name="chooser_predictor_bits" value="2"/>
+ <!-- These parameters can be combined like below in next version
+ <param name="load_predictor" value="10,3,1024"/>
+ <param name="global_predictor" value="4096,2"/>
+ <param name="predictor_chooser" value="4096,2"/>
+ -->
+ </component>
+ <component id="system.core0.itlb" name="itlb">
+ <param name="number_entries" value="1"/>
+ <stat name="total_accesses" value="0"/>
+ <stat name="total_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <!-- there is no write requests to itlb although writes happen to itlb after miss,
+ which is actually a replacement -->
+ </component>
+ <component id="system.core0.icache" name="icache">
+ <!-- there is no write requests to itlb although writes happen to it after miss,
+ which is actually a replacement -->
+ <param name="icache_config" value="16384,128,4,1,1,3,8,0"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <!-- cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate -->
+ <param name="buffer_sizes" value="16, 16, 16,0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="total_instructions_match_mcpat"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.dtlb" name="dtlb">
+ <param name="number_entries" value="1"/>
+ <stat name="total_accesses" value="0"/>
+ <stat name="total_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.ccache" name="ccache">
+ <!-- all the buffer related are optional -->
+ <param name="ccache_config" value="16384,64,2,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="ccache_read_accesses_match_mcpat"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="ccache_read_misses_match_mcpat"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.tcache" name="tcache">
+ <!-- all the buffer related are optional -->
+ <param name="tcache_config" value="49152,128,8,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="tcache_read_accesses_match_mcpat"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="tcache_read_misses_match_mcpat"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <!--model the shared memory by mimicing dcache-->
+ <component id="system.core0.sharedmemory" name="sharedmemory">
+ <!-- all the buffer related are optional -->
+ <param name="sharedmemory_config" value="98304,16,1,16,1,3,16,0"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="sharedmemory_read_access_match_mcpat"/>
+ <stat name="write_accesses" value="sharedmemory_write_access_match_mcpat"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.dcache" name="dcache">
+ <!-- all the buffer related are optional -->
+ <param name="dcache_config" value="16384,32,4,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="dcache_read_access_match_mcpat"/>
+ <stat name="write_accesses" value="dcache_write_access_match_mcpat"/>
+ <stat name="read_misses" value="dcache_read_miss_match_mcpat"/>
+ <stat name="write_misses" value="dcache_write_miss_match_mcpat"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.BTB" name="BTB">
+ <!-- all the buffer related are optional -->
+ <param name="BTB_config" value="8192,4,2,1, 1,3"/>
+ <!-- the parameters are capacity,block_width,associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ </component>
+ </component>
+ <component id="system.L1Directory0" name="L1Directory0">
+ <param name="Directory_type" value="0"/>
+ <!--0 cam based shadowed tag. 1 directory cache -->
+ <param name="Dir_config" value="2048,1,0,1, 4, 4,8"/>
+ <!-- the parameters are capacity,block_width, associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ <param name="buffer_sizes" value="8, 8, 8, 8"/>
+ <!-- all the buffer related are optional -->
+ <param name="clockrate" value="1400"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw search ports -->
+ <param name="device_type" value="0"/>
+ <!-- altough there are multiple access types,
+ Performance simulator needs to cast them into reads or writes
+ e.g. the invalidates can be considered as writes -->
+ <stat name="read_accesses" value="800000"/>
+ <stat name="write_accesses" value="27276"/>
+ <stat name="read_misses" value="1632"/>
+ <stat name="write_misses" value="183"/>
+ <stat name="conflicts" value="20"/>
+ <stat name="duty_cycle" value="0.45"/>
+ </component>
+ <component id="system.L2Directory0" name="L2Directory0">
+ <param name="Directory_type" value="1"/>
+ <!--0 cam based shadowed tag. 1 directory cache -->
+ <param name="Dir_config" value="1048576,16,16,1,2, 100"/>
+ <!-- the parameters are capacity,block_width, associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ <param name="buffer_sizes" value="8, 8, 8, 8"/>
+ <!-- all the buffer related are optional -->
+ <param name="clockrate" value="1400"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw search ports -->
+ <param name="device_type" value="0"/>
+ <!-- altough there are multiple access types,
+ Performance simulator needs to cast them into reads or writes
+ e.g. the invalidates can be considered as writes -->
+ <stat name="read_accesses" value="0"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.45"/>
+ </component>
+ <component id="system.L20" name="L20">
+ <!-- all the buffer related are optional -->
+ <param name="L2_config" value="131072,128,16,1, 4,23, 64, 1"/>
+ <!-- consider 4-way bank interleaving for Niagara 1 -->
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <param name="clockrate" value="2962"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw ports -->
+ <param name="device_type" value="0"/>
+ <stat name="read_accesses" value="200000"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.5"/>
+ </component>
+
+<!--**********************************************************************-->
+<component id="system.L30" name="L30">
+ <param name="L3_config" value="1048576,64,16,1, 2,100, 64,1"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="clockrate" value="3500"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw ports -->
+ <param name="device_type" value="0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="58824"/>
+ <stat name="write_accesses" value="27276"/>
+ <stat name="read_misses" value="1632"/>
+ <stat name="write_misses" value="183"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.35"/>
+ </component>
+
+
+<!--**********************************************************************-->
+ <component id="system.NoC0" name="noc0">
+ <param name="clockrate" value="700"/>
+ <param name="type" value="1"/>
+ <!-- 1 NoC, O bus -->
+ <param name="horizontal_nodes" value="2"/>
+ <param name="vertical_nodes" value="1"/>
+ <param name="has_global_link" value="0"/>
+ <!-- 1 has global link, 0 does not have global link -->
+ <param name="link_throughput" value="1"/><!--w.r.t clock -->
+ <param name="link_latency" value="1"/><!--w.r.t clock -->
+ <!-- througput >= latency -->
+ <!-- Router architecture -->
+ <param name="input_ports" value="6"/>
+ <param name="output_ports" value="6"/>
+ <param name="virtual_channel_per_port" value="1"/>
+ <!-- input buffer; in classic routers only input ports need buffers -->
+ <param name="flit_bits" value="32"/>
+ <param name="input_buffer_entries_per_vc" value="1"/><!--VCs within the same ports share input buffers whose size is propotional to the number of VCs-->
+ <param name="chip_coverage" value="1"/>
+ <!-- When multiple NOC present, one NOC will cover part of the whole chip. chip_coverage <=1 -->
+ <stat name="total_accesses" value="0"/>
+ <!-- This is the number of total accesses within the whole network not for each router -->
+ <stat name="duty_cycle" value="0.6"/>
+ </component>
+<!--**********************************************************************-->
+<!--**********************************************************************-->
+
+ <component id="system.mem" name="mem">
+ <!-- Main memory property -->
+ <param name="mem_tech_node" value="23"/>
+ <param name="device_clock" value="200"/><!--MHz, this is clock rate of the actual memory device, not the FSB -->
+ <param name="peak_transfer_rate" value="3200"/><!--MB/S-->
+ <param name="internal_prefetch_of_DRAM_chip" value="4"/>
+ <!-- 2 for DDR, 4 for DDR2, 8 for DDR3...-->
+ <!-- the device clock, peak_transfer_rate, and the internal prefetch decide the DIMM property -->
+ <!-- above numbers can be easily found from Wikipedia -->
+ <param name="capacity_per_channel" value="4096"/> <!-- MB -->
+ <!-- capacity_per_Dram_chip=capacity_per_channel/number_of_dimms/number_ranks/Dram_chips_per_rank
+ Current McPAT assumes single DIMMs are used.-->
+ <param name="number_ranks" value="2"/>
+ <param name="num_banks_of_DRAM_chip" value="6"/>
+ <param name="Block_width_of_DRAM_chip" value="64"/> <!-- B -->
+ <param name="output_width_of_DRAM_chip" value="8"/>
+ <!--number of Dram_chips_per_rank=" 72/output_width_of_DRAM_chip-->
+ <!--number of Dram_chips_per_rank=" 72/output_width_of_DRAM_chip-->
+ <param name="page_size_of_DRAM_chip" value="8"/> <!-- 8 or 16 -->
+ <param name="burstlength_of_DRAM_chip" value="8"/>
+ <stat name="memory_accesses" value="1052"/>
+ <stat name="memory_reads" value="1052"/>
+ <stat name="memory_writes" value="1052"/>
+ </component>
+ <component id="system.mc" name="mc">
+ <!-- Memeory controllers are for DDR(2,3...) DIMMs -->
+ <!-- current version of McPAT uses published values for base parameters of memory controller
+ improvments on MC will be added in later versions. -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="mc_clock" value="1848"/><!--DIMM IO bus clock rate MHz DDR2-400 for Niagara 1-->
+ <param name="peak_transfer_rate" value="29568"/><!--MB/S Syed: GTX 470 has 177.4GB/s mem transfer rate with 6 MCs -->
+ <param name="block_size" value="64"/><!--B-->
+ <param name="number_mcs" value="6"/><!-- 6 GDDR5 memory controllers -->
+ <!-- current McPAT only supports homogeneous memory controllers -->
+ <param name="memory_channels_per_mc" value="2"/>
+ <param name="number_ranks" value="1"/>
+ <param name="withPHY" value="0"/>
+ <!-- # of ranks of each channel-->
+ <param name="req_window_size_per_channel" value="16"/>
+ <param name="IO_buffer_size_per_channel" value="16"/>
+ <param name="databus_width" value="32"/>
+ <param name="addressbus_width" value="32"/>
+ <param name="PRT_entries" value="32"/>
+ <!-- # of empirical DRAM model parameter -->
+ <param name="dram_cmd_coeff" value="0"/>
+ <param name="dram_act_coeff" value="0"/>
+ <param name="dram_nop_coeff" value="0"/>
+ <param name="dram_activity_coeff" value="0"/>
+ <param name="dram_pre_coeff" value="3.8475e-8f"/>
+ <param name="dram_rd_coeff" value="7.74707143e-8f"/>
+ <param name="dram_wr_coeff" value="3.54664286e-8f"/>
+ <param name="dram_req_coeff" value="0"/>
+ <param name="dram_const_coeff" value="0"/>
+
+ <!-- McPAT will add the control bus width to the addressbus width automatically -->
+ <stat name="memory_accesses" value="memory_accesses_match_mcpat"/>
+ <stat name="memory_reads" value="memory_reads_match_mcpat"/>
+ <stat name="memory_writes" value="memory_writes_match_mcpat"/>
+ <!-- McPAT does not track individual mc, instead, it takes the total accesses and calculate
+ the average power per MC or per channel. This is sufficent for most application.
+ Further trackdown can be easily added in later versions. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.niu" name="niu">
+ <!-- On chip 10Gb Ethernet NIC, including XAUI Phy and MAC controller -->
+ <!-- For a minimum IP packet size of 84B at 10Gb/s, a new packet arrives every 67.2ns.
+ the low bound of clock rate of a 10Gb MAC is 150Mhz -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="clockrate" value="350"/>
+ <param name="number_units" value="0"/> <!-- unlike PCIe and memory controllers, each Ethernet controller only have one port -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- ratio of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual nic, instead, it takes the total accesses and calculate
+ the average power per nic or per channel. This is sufficent for most application. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.pcie" name="pcie">
+ <!-- On chip PCIe controller, including Phy-->
+ <!-- For a minimum PCIe packet size of 84B at 8Gb/s per lane (PCIe 3.0), a new packet arrives every 84ns.
+ the low bound of clock rate of a PCIe per lane logic is 120Mhz -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="withPHY" value="1"/>
+ <param name="clockrate" value="350"/>
+ <param name="number_units" value="0"/>
+ <param name="num_channels" value="8"/> <!-- 2 ,4 ,8 ,16 ,32 -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- Percentage of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual pcie controllers, instead, it takes the total accesses and calculate
+ the average power per pcie controller or per channel. This is sufficent for most application. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.flashc" name="flashc">
+ <param name="number_flashcs" value="0"/>
+ <param name="type" value="1"/> <!-- 1: low power; 0 high performance -->
+ <param name="withPHY" value="1"/>
+ <param name="peak_transfer_rate" value="200"/><!--Per controller sustainable reak rate MB/S -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- Percentage of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual flash controller, instead, it takes the total accesses and calculate
+ the average power per fc or per channel. This is sufficent for most application -->
+ </component>
+<!--**********************************************************************-->
+
+ </component>
+</component>
\ No newline at end of file diff --git a/configs/tested-cfgs/SM7_GV100/accelwattch_sass_sim.xml b/configs/tested-cfgs/SM7_GV100/accelwattch_sass_sim.xml new file mode 100644 index 0000000..570332d --- /dev/null +++ b/configs/tested-cfgs/SM7_GV100/accelwattch_sass_sim.xml @@ -0,0 +1,613 @@ +<?xml version="1.0" ?>
+<component id="root" name="root">
+ <component id="system" name="system">
+<!-- Copyright (c) 2018-2021, Vijay Kandiah, Junrui Pan, Mahmoud Khairy, Scott Peverelle, Timothy Rogers, Tor M. Aamodt, Nikos Hardavellas
+Northwestern University, Purdue University, The University of British Columbia
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer;
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution;
+3. Neither the names of Northwestern University, Purdue University,
+ The University of British Columbia nor the names of their contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE. -->
+
+ <!-- DYNAMIC Power Activity Factors -->
+
+ <param name="TOT_INST" value="10" /> <!--Instruction Buffer Activity Factor(Total Warp Instructions)-->
+ <param name="FP_INT" value="4.661" /> <!--Scheduler Activity Factor(Non-Memory Warp Instructons)-->
+ <param name="IC_H" value="8.593489331" /> <!--Instruction Cache Hits -->
+ <param name="IC_M" value="29.735231" /> <!--Instruction Cache Misses-->
+ <param name="DC_RH" value="9.835033124" /> <!--L1 Data Cache Read Hits-->
+ <param name="DC_RM" value="10.95446778" /> <!--L1 Data Cache Read Misses-->
+ <param name="DC_WH" value="0.679656761" /> <!--L1 Data Cache Write Hits-->
+ <param name="DC_WM" value="17.67551799" /> <!--L1 Data Cache Write Misses-->
+ <param name="CC_H" value="0.1107" /> <!--Constant Cache Hits-->
+ <param name="CC_M" value="0.1233" /> <!--Constant Cache Misses-->
+ <param name="SHRD_ACC" value="0.779992642" /> <!--Shared Memory Accesses-->
+ <param name="REG_RD" value="0.100560581" /> <!--Register Reads-->
+ <param name="REG_WR" value="0.140604679" /> <!--Register Writes-->
+ <param name="INT_ACC" value="14.98768151" /> <!--Integer ALU Accesses-->
+ <param name="FP_ACC" value="0.529670751" /> <!--FPU Accesses-->
+ <param name="DP_ACC" value="0.777229051" /> <!--Integer Accesses-->
+ <param name="INT_MUL_ACC" value="0.115098047" /> <!--Integer MUL Accesses-->
+ <param name="FP_MUL_ACC" value="0.089517055" /> <!--FP MUL Accesses-->
+ <param name="FP_SQRT_ACC" value="0.195089274" /> <!--SFU: sqrt Accesses-->
+ <param name="FP_LG_ACC" value="0.125521663" /> <!--SFU: log Accesses-->
+ <param name="FP_SIN_ACC" value="0.13336307" /> <!--SFU: sin/cos Accesses-->
+ <param name="FP_EXP_ACC" value="0.36204415" /> <!--SFU: exponent Accesses-->
+ <param name="DP_MUL_ACC" value="0.1321288" /> <!--DP MUL Accesses-->
+ <param name="TENSOR_ACC" value="0.815454621" /> <!--Tensor Accesses-->
+ <param name="TEX_ACC" value="0.115100088" /> <!--Texture Unit Accesses-->
+ <param name="MEM_RD" value="0.025941068" /> <!--DRAM Reads-->
+ <param name="MEM_WR" value="0.031443719" /> <!--DRAM Writes-->
+ <param name="MEM_PRE" value="0.008647023" /> <!--DRAM Precharge-->
+ <param name="L2_RH" value="1.260867526" /> <!--L2 Data Cache Read Hits-->
+ <param name="L2_RM" value="2.394535301" /> <!--L2 Data Cache Read Misses-->
+ <param name="L2_WH" value="4.124916" /> <!--L2 Data Cache Write Hits-->
+ <param name="L2_WM" value="1.222707601" /> <!--L2 Data Cache Write Misses-->
+ <param name="NOC_A" value="32.09037703" /> <!--Interconnect Network Accesses-->
+ <param name="PIPE_A" value="0.514" /> <!--Pipeline Accesses-->
+
+ <!-- STATIC & CONSTANT Power -->
+
+ <param name="constant_power" value="32.32522272" /> <!--Constant power-->
+ <param name="idle_core_power" value="0.28279166"/> <!--Idle SM power-->
+
+ <param name="static_cat1_flane" value="15.29035866"/> <!--INT (ADD+MUL) First Lane Activation Power-->
+ <param name="static_cat1_addlane" value="0.586233603"/> <!--INT (ADD+MUL) Additional Lane Activation Power-->
+
+ <param name="static_cat2_flane" value="18.6179906"/> <!--INT+FP First Lane Activation Power-->
+ <param name="static_cat2_addlane" value="0.645228013"/> <!--INT+FP Additional Lane Activation Power-->
+
+ <param name="static_cat3_flane" value="19.10017723"/> <!--INT+FP+DP First Lane Activation Power-->
+ <param name="static_cat3_addlane" value="0.726863055"/> <!--INT+FP+DP Additional Lane Activation Power-->
+
+ <param name="static_cat4_flane" value="18.55029744"/> <!--INT+FP+SFU First Lane Activation Power-->
+ <param name="static_cat4_addlane" value="0.6099397"/> <!--INT+FP+SFU Additional Lane Activation Power-->
+
+ <param name="static_cat5_flane" value="14.74826681"/> <!--INT+FP+TEX First Lane Activation Power-->
+ <param name="static_cat5_addlane" value="0.514367937"/> <!--INT+FP+TEX Additional Lane Activation Power-->
+
+ <param name="static_cat6_flane" value="48.94875596"/> <!--INT+FP+TENSOR First Lane Activation Power-->
+ <param name="static_cat6_addlane" value="0.0"/> <!--INT+FP+TENSOR Additional Lane Activation Power-->
+
+ <param name="static_light_flane" value="1.965373811"/> <!--LIGHT_SM First Lane Activation Power-->
+ <param name="static_light_addlane" value="0.003966868"/> <!--LIGHT_SM Additional Lane Activation Power-->
+
+ <param name="static_intadd_flane" value="19.70468506"/> <!--INT ADD First Lane Activation Power-->
+ <param name="static_intadd_addlane" value="0.388578623"/> <!--INT ADD Additional Lane Activation Power-->
+
+ <param name="static_intmul_flane" value="16.64811823"/> <!--INT MUL First Lane Activation Power-->
+ <param name="static_intmul_addlane" value="0.281803166"/> <!--INT MUL Additional Lane Activation Power-->
+
+ <param name="static_geomean_flane" value="17.21745077"/> <!--GEOMEAN First Lane Activation Power-->
+ <param name="static_geomean_addlane" value="0.650630555"/> <!--GEOMEAN Additional Lane Activation Power-->
+ <param name="static_shared_flane" value="31.40965691"/> <!--Shared Memory First Lane Activation Power-->
+ <param name="static_l1_flane" value="34.79491352"/> <!--L1D First Lane Activation Power-->
+ <param name="static_l2_flane" value="17.30654755"/> <!--L2D ADD+MUL First Lane Activation Power-->
+
+
+ <!-- LEAVE BELOW UNCHANGED! These are parameters used for initial GPUWattch model left untouched -->
+
+
+ <param name="GPU_Architecture" value="1"/><!-- 0-G80; 1-Fermi; others not supported -->
+ <param name="architecture" value="1"/> <!-- fermi:1 quadro:2 other: undefined-->
+ <param name="number_of_L1Directories" value="0"/>
+ <param name="number_of_L2Directories" value="0"/>
+ <param name="number_of_L2s" value="1"/> <!-- This number means how many L2 clusters in each cluster there can be multiple banks/ports -->
+ <param name="number_of_L3s" value="0"/> <!-- This number means how many L3 clusters -->
+ <param name="number_of_NoCs" value="1"/>
+ <param name="homogeneous_cores" value="1"/><!--1 means homo -->
+ <param name="homogeneous_L2s" value="1"/>
+ <param name="homogeneous_L1Directorys" value="1"/>
+ <param name="homogeneous_L2Directorys" value="1"/>
+ <param name="homogeneous_L3s" value="1"/>
+ <param name="homogeneous_ccs" value="1"/><!--cache coherece hardware -->
+ <param name="homogeneous_NoCs" value="1"/>
+ <param name="core_tech_node" value="23"/><!-- nm -->
+
+ <param name="number_cache_levels" value="2"/>
+ <param name="interconnect_projection_type" value="0"/><!--0: agressive wire technology; 1: conservative wire technology -->
+ <param name="device_type" value="0"/><!--0: HP(High Performance Type); 1: LSTP(Low standby power) 2: LOP (Low Operating Power) -->
+ <param name="longer_channel_device" value="1"/><!-- 0 no use; 1 use when possible -->
+ <param name="machine_bits" value="32"/>
+ <param name="virtual_address_width" value="32"/>
+ <param name="physical_address_width" value="32"/>
+ <param name="virtual_memory_page_size" value="4096"/>
+
+ <param name="IDLE_CORE_N" value="1"/>
+ <stat name="num_idle_cores" value="0"/><!-- Average Number of idle cores during this period -->
+ <stat name="total_cycles" value="total_cycles_match_mcpat"/>
+ <stat name="idle_cycles" value="idle_cycles_match_mcpat"/>
+ <stat name="busy_cycles" value="busy_cycles_match_mcpat"/>
+ <!--This page size(B) is complete different from the page size in Main memo secction. this page size is the size of
+ virtual memory from OS/Archi perspective; the page size in Main memo secction is the actuall physical line in a DRAM bank -->
+ <!-- *********************** cores ******************* -->
+ <component id="system.core0" name="core0">
+ <!-- Core property -->
+ <param name="clock_rate" value="700"/>
+ <param name="instruction_length" value="32"/>
+ <param name="opcode_width" value="9"/>
+ <!-- address width determins the tag_width in Cache, LSQ and buffers in cache controller
+ default value is machine_bits, if not set -->
+ <param name="machine_type" value="1"/><!-- 1 inorder; 0 OOO-->
+ <!-- inorder/OoO -->
+ <param name="number_hardware_threads" value="32"/>
+ <!-- number_instruction_fetch_ports(icache ports) is always 1 in single-thread processor,
+ it only may be more than one in SMT processors. BTB ports always equals to fetch ports since
+ branch information in consective branch instructions in the same fetch group can be read out from BTB once.-->
+ <param name="fetch_width" value="1"/>
+ <!-- fetch_width determins the size of cachelines of L1 cache block -->
+ <param name="number_instruction_fetch_ports" value="1"/>
+ <param name="decode_width" value="1"/>
+ <!-- decode_width determins the number of ports of the
+ renaming table (both RAM and CAM) scheme -->
+ <param name="issue_width" value="2"/>
+ <!-- issue_width determins the number of ports of Issue window and other logic
+ as in the complexity effective proccessors paper; issue_width==dispatch_width -->
+ <param name="commit_width" value="2"/>
+ <!-- commit_width determins the number of ports of register files -->
+ <param name="fp_issue_width" value="1"/>
+ <param name="prediction_width" value="0"/>
+ <!-- number of branch instructions can be predicted simultannouesl-->
+ <!-- Current version of McPAT does not distinguish int and floating point pipelines
+ Theses parameters are reserved for future use.-->
+ <param name="pipelines_per_core" value="1,1"/>
+ <!--integer_pipeline and floating_pipelines, if the floating_pipelines is 0, then the pipeline is shared-->
+ <param name="pipeline_depth" value="8,8"/>
+ <!-- pipeline depth of int and fp, if pipeline is shared, the second number is the average cycles of fp ops -->
+ <!-- issue and exe unit-->
+ <param name="ALU_per_core" value="32"/>
+ <!-- contains an adder, a shifter, and a logical unit -->
+ <param name="MUL_per_core" value="4"/>
+ <!-- For MUL and Div -->
+ <param name="FPU_per_core" value="32"/>
+ <!-- buffer between IF and ID stage -->
+ <param name="instruction_buffer_size" value="1"/>
+ <!-- buffer between ID and sche/exe stage -->
+ <param name="decoded_stream_buffer_size" value="1"/>
+ <param name="instruction_window_scheme" value="0"/><!-- 0 PHYREG based, 1 RSBASED-->
+ <!-- McPAT support 2 types of OoO cores, RS based and physical reg based-->
+ <param name="instruction_window_size" value="1"/>
+ <param name="fp_instruction_window_size" value="1"/>
+ <!-- the instruction issue Q as in Alpha 21264; The RS as in Intel P6 -->
+ <param name="ROB_size" value="0"/>
+ <!-- each in-flight instruction has an entry in ROB -->
+ <!-- registers -->
+ <!-- SM parameters Added by Syed Gilani -->
+ <param name="rf_banks" value="32"/>
+ <param name="simd_width" value="32"/>
+ <param name="collector_units" value="32"/>
+ <param name="core_clock_ratio" value="2"/>
+ <param name="warp_size" value="32"/>
+
+ <param name="archi_Regs_IRF_size" value="65536"/>
+ <param name="archi_Regs_FRF_size" value="32"/>
+ <!-- if OoO processor, phy_reg number is needed for renaming logic,
+ renaming logic is for both integer and floating point insts. -->
+ <param name="phy_Regs_IRF_size" value="32"/>
+ <param name="phy_Regs_FRF_size" value="32"/>
+ <!-- rename logic -->
+ <param name="rename_scheme" value="0"/>
+ <!-- can be RAM based(0) or CAM based(1) rename scheme
+ RAM-based scheme will have free list, status table;
+ CAM-based scheme have the valid bit in the data field of the CAM
+ both RAM and CAM need RAM-based checkpoint table, checkpoint_depth=# of in_flight instructions;
+ Detailed RAT Implementation see TR -->
+ <param name="register_windows_size" value="0"/>
+ <!-- how many windows in the windowed register file, sun processors;
+ no register windowing is used when this number is 0 -->
+ <!-- In OoO cores, loads and stores can be issued whether inorder(Pentium Pro) or (OoO)out-of-order(Alpha),
+ They will always try to exeute out-of-order though. -->
+ <param name="LSU_order" value="inorder"/>
+ <param name="store_buffer_size" value="32"/>
+ <!-- By default, in-order cores do not have load buffers -->
+ <param name="load_buffer_size" value="32"/>
+ <!-- number of ports refer to sustainable concurrent memory accesses -->
+ <param name="memory_ports" value="2"/>
+ <!-- max_allowed_in_flight_memo_instructions determins the # of ports of load and store buffer
+ as well as the ports of Dcache which is connected to LSU -->
+ <!-- dual-pumped Dcache can be used to save the extra read/write ports -->
+ <param name="RAS_size" value="1"/>
+ <!-- general stats, defines simulation periods;require total, idle, and busy cycles for senity check -->
+ <!-- please note: if target architecture is X86, then all the instrucions refer to (fused) micro-ops -->
+ <stat name="total_instructions" value="total_instructions_match_mcpat"/>
+ <stat name="int_instructions" value="int_instruction_match_mcpat"/>
+ <stat name="fp_instructions" value="flt_instruction_match_mcpat"/>
+ <stat name="branch_instructions" value="branch_instruction_match_mcpat"/>
+ <stat name="branch_mispredictions" value="0"/>
+ <stat name="load_instructions" value="load_instruction_match_mcpat"/>
+ <stat name="store_instructions" value="store_instruction_match_mcpat"/>
+ <stat name="committed_instructions" value="total_instructions_match_mcpat"/>
+ <stat name="committed_int_instructions" value="int_instruction_match_mcpat"/>
+ <stat name="committed_fp_instructions" value="flt_instruction_match_mcpat"/>
+ <stat name="pipeline_duty_cycle" value="0.6"/><!--<=1, runtime_ipc/peak_ipc; averaged for all cores if homogenous -->
+ <!-- the following cycle stats are used for heterogeneouse cores only,
+ please ignore them if homogeneouse cores -->
+ <stat name="total_cycles" value="total_cycles_match_mcpat"/>
+ <stat name="idle_cycles" value="idle_cycles_match_mcpat"/>
+ <stat name="busy_cycles" value="busy_cycles_match_mcpat"/>
+ <!-- instruction buffer stats -->
+ <!-- ROB stats, both RS and Phy based OoOs have ROB
+ performance simulator should capture the difference on accesses,
+ otherwise, McPAT has to guess based on number of commited instructions. -->
+ <stat name="ROB_reads" value="263886"/>
+ <stat name="ROB_writes" value="263886"/>
+ <!-- RAT accesses -->
+ <stat name="rename_accesses" value="263886"/>
+ <stat name="fp_rename_accesses" value="263886"/>
+ <!-- decode and rename stage use this, should be total ic - nop -->
+ <!-- Inst window stats -->
+ <stat name="inst_window_reads" value="263886"/>
+ <stat name="inst_window_writes" value="263886"/>
+ <stat name="inst_window_wakeup_accesses" value="263886"/>
+ <stat name="fp_inst_window_reads" value="263886"/>
+ <stat name="fp_inst_window_writes" value="263886"/>
+ <stat name="fp_inst_window_wakeup_accesses" value="263886"/>
+ <!-- RF accesses -->
+ <stat name="int_regfile_reads" value="int_register_read_access_match_mcpat"/>
+ <stat name="float_regfile_reads" value="int_register_write_access_match_mcpat"/>
+ <stat name="int_regfile_writes" value="float_register_read_access_match_mcpat"/>
+ <stat name="float_regfile_writes" value="float_register_write_access_match_mcpat"/>
+
+ <!-- The following stat is for operand collector power - Added by Syed -->
+ <stat name="non_rf_operands" value="0"/>
+
+ <!-- accesses to the working reg -->
+ <stat name="function_calls" value="0"/>
+ <stat name="context_switches" value="0"/> <!--not used in the McPAT -->
+ <!-- Number of Windowes switches (number of function calls and returns)-->
+ <!-- Alu stats by default, the processor has one FPU that includes the divider and
+ multiplier. The fpu accesses should include accesses to multiplier and divider -->
+ <stat name="ialu_accesses" value="ialu_accesses_match_mcpat"/>
+ <stat name="fpu_accesses" value="fpu_accesses_match_mcpat"/>
+ <stat name="mul_accesses" value="mul_accesses_match_mcpat"/>
+ <stat name="cdb_alu_accesses" value="0"/>
+ <stat name="cdb_mul_accesses" value="0"/>
+ <stat name="cdb_fpu_accesses" value="0"/>
+ <!-- multiple cycle accesses should be counted multiple times,
+ otherwise, McPAT can use internal counter for different floating point instructions
+ to get final accesses. But that needs detailed info for floating point inst mix -->
+ <!-- currently the performance simulator should
+ make sure all the numbers are final numbers,
+ including the explicit read/write accesses,
+ and the implicite accesses such as replacements and etc.
+ Future versions of McPAT may be able to reason the implicite access
+ based on param and stats of last level cache
+ The same rule applies to all cache access stats too! -->
+ <!-- following is AF for max power computation.
+ Do not change them, unless you understand them-->
+ <stat name="IFU_duty_cycle" value="0.25"/>
+ <stat name="LSU_duty_cycle" value="0.25"/>
+ <stat name="MemManU_I_duty_cycle" value="1"/>
+ <stat name="MemManU_D_duty_cycle" value="0.25"/>
+ <stat name="ALU_duty_cycle" value="0.9"/>
+ <stat name="MUL_duty_cycle" value="0.5"/>
+ <stat name="FPU_duty_cycle" value="1"/><!-- FPU numbers are already average -->
+ <stat name="ALU_cdb_duty_cycle" value="0.9"/>
+ <stat name="MUL_cdb_duty_cycle" value="0.5"/>
+ <stat name="FPU_cdb_duty_cycle" value="15"/>
+ <component id="system.core0.predictor" name="PBT">
+ <!-- branch predictor; tournament predictor see Alpha implementation -->
+ <param name="local_predictor_size" value="10,3"/>
+ <param name="local_predictor_entries" value="1024"/>
+ <param name="global_predictor_entries" value="4096"/>
+ <param name="global_predictor_bits" value="2"/>
+ <param name="chooser_predictor_entries" value="4096"/>
+ <param name="chooser_predictor_bits" value="2"/>
+ <!-- These parameters can be combined like below in next version
+ <param name="load_predictor" value="10,3,1024"/>
+ <param name="global_predictor" value="4096,2"/>
+ <param name="predictor_chooser" value="4096,2"/>
+ -->
+ </component>
+ <component id="system.core0.itlb" name="itlb">
+ <param name="number_entries" value="1"/>
+ <stat name="total_accesses" value="0"/>
+ <stat name="total_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <!-- there is no write requests to itlb although writes happen to itlb after miss,
+ which is actually a replacement -->
+ </component>
+ <component id="system.core0.icache" name="icache">
+ <!-- there is no write requests to itlb although writes happen to it after miss,
+ which is actually a replacement -->
+ <param name="icache_config" value="16384,128,4,1,1,3,8,0"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <!-- cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate -->
+ <param name="buffer_sizes" value="16, 16, 16,0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="total_instructions_match_mcpat"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.dtlb" name="dtlb">
+ <param name="number_entries" value="1"/>
+ <stat name="total_accesses" value="0"/>
+ <stat name="total_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.ccache" name="ccache">
+ <!-- all the buffer related are optional -->
+ <param name="ccache_config" value="16384,64,2,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="ccache_read_accesses_match_mcpat"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="ccache_read_misses_match_mcpat"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.tcache" name="tcache">
+ <!-- all the buffer related are optional -->
+ <param name="tcache_config" value="49152,128,8,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="tcache_read_accesses_match_mcpat"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="tcache_read_misses_match_mcpat"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <!--model the shared memory by mimicing dcache-->
+ <component id="system.core0.sharedmemory" name="sharedmemory">
+ <!-- all the buffer related are optional -->
+ <param name="sharedmemory_config" value="98304,16,1,16,1,3,16,0"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="sharedmemory_read_access_match_mcpat"/>
+ <stat name="write_accesses" value="sharedmemory_write_access_match_mcpat"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.dcache" name="dcache">
+ <!-- all the buffer related are optional -->
+ <param name="dcache_config" value="16384,32,4,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="dcache_read_access_match_mcpat"/>
+ <stat name="write_accesses" value="dcache_write_access_match_mcpat"/>
+ <stat name="read_misses" value="dcache_read_miss_match_mcpat"/>
+ <stat name="write_misses" value="dcache_write_miss_match_mcpat"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.BTB" name="BTB">
+ <!-- all the buffer related are optional -->
+ <param name="BTB_config" value="8192,4,2,1, 1,3"/>
+ <!-- the parameters are capacity,block_width,associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ </component>
+ </component>
+ <component id="system.L1Directory0" name="L1Directory0">
+ <param name="Directory_type" value="0"/>
+ <!--0 cam based shadowed tag. 1 directory cache -->
+ <param name="Dir_config" value="2048,1,0,1, 4, 4,8"/>
+ <!-- the parameters are capacity,block_width, associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ <param name="buffer_sizes" value="8, 8, 8, 8"/>
+ <!-- all the buffer related are optional -->
+ <param name="clockrate" value="1400"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw search ports -->
+ <param name="device_type" value="0"/>
+ <!-- altough there are multiple access types,
+ Performance simulator needs to cast them into reads or writes
+ e.g. the invalidates can be considered as writes -->
+ <stat name="read_accesses" value="800000"/>
+ <stat name="write_accesses" value="27276"/>
+ <stat name="read_misses" value="1632"/>
+ <stat name="write_misses" value="183"/>
+ <stat name="conflicts" value="20"/>
+ <stat name="duty_cycle" value="0.45"/>
+ </component>
+ <component id="system.L2Directory0" name="L2Directory0">
+ <param name="Directory_type" value="1"/>
+ <!--0 cam based shadowed tag. 1 directory cache -->
+ <param name="Dir_config" value="1048576,16,16,1,2, 100"/>
+ <!-- the parameters are capacity,block_width, associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ <param name="buffer_sizes" value="8, 8, 8, 8"/>
+ <!-- all the buffer related are optional -->
+ <param name="clockrate" value="1400"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw search ports -->
+ <param name="device_type" value="0"/>
+ <!-- altough there are multiple access types,
+ Performance simulator needs to cast them into reads or writes
+ e.g. the invalidates can be considered as writes -->
+ <stat name="read_accesses" value="0"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.45"/>
+ </component>
+ <component id="system.L20" name="L20">
+ <!-- all the buffer related are optional -->
+ <param name="L2_config" value="131072,128,16,1, 4,23, 64, 1"/>
+ <!-- consider 4-way bank interleaving for Niagara 1 -->
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <param name="clockrate" value="2962"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw ports -->
+ <param name="device_type" value="0"/>
+ <stat name="read_accesses" value="200000"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.5"/>
+ </component>
+
+<!--**********************************************************************-->
+<component id="system.L30" name="L30">
+ <param name="L3_config" value="1048576,64,16,1, 2,100, 64,1"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="clockrate" value="3500"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw ports -->
+ <param name="device_type" value="0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="58824"/>
+ <stat name="write_accesses" value="27276"/>
+ <stat name="read_misses" value="1632"/>
+ <stat name="write_misses" value="183"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.35"/>
+ </component>
+
+
+<!--**********************************************************************-->
+ <component id="system.NoC0" name="noc0">
+ <param name="clockrate" value="700"/>
+ <param name="type" value="1"/>
+ <!-- 1 NoC, O bus -->
+ <param name="horizontal_nodes" value="2"/>
+ <param name="vertical_nodes" value="1"/>
+ <param name="has_global_link" value="0"/>
+ <!-- 1 has global link, 0 does not have global link -->
+ <param name="link_throughput" value="1"/><!--w.r.t clock -->
+ <param name="link_latency" value="1"/><!--w.r.t clock -->
+ <!-- througput >= latency -->
+ <!-- Router architecture -->
+ <param name="input_ports" value="6"/>
+ <param name="output_ports" value="6"/>
+ <param name="virtual_channel_per_port" value="1"/>
+ <!-- input buffer; in classic routers only input ports need buffers -->
+ <param name="flit_bits" value="32"/>
+ <param name="input_buffer_entries_per_vc" value="1"/><!--VCs within the same ports share input buffers whose size is propotional to the number of VCs-->
+ <param name="chip_coverage" value="1"/>
+ <!-- When multiple NOC present, one NOC will cover part of the whole chip. chip_coverage <=1 -->
+ <stat name="total_accesses" value="0"/>
+ <!-- This is the number of total accesses within the whole network not for each router -->
+ <stat name="duty_cycle" value="0.6"/>
+ </component>
+<!--**********************************************************************-->
+<!--**********************************************************************-->
+
+ <component id="system.mem" name="mem">
+ <!-- Main memory property -->
+ <param name="mem_tech_node" value="23"/>
+ <param name="device_clock" value="200"/><!--MHz, this is clock rate of the actual memory device, not the FSB -->
+ <param name="peak_transfer_rate" value="3200"/><!--MB/S-->
+ <param name="internal_prefetch_of_DRAM_chip" value="4"/>
+ <!-- 2 for DDR, 4 for DDR2, 8 for DDR3...-->
+ <!-- the device clock, peak_transfer_rate, and the internal prefetch decide the DIMM property -->
+ <!-- above numbers can be easily found from Wikipedia -->
+ <param name="capacity_per_channel" value="4096"/> <!-- MB -->
+ <!-- capacity_per_Dram_chip=capacity_per_channel/number_of_dimms/number_ranks/Dram_chips_per_rank
+ Current McPAT assumes single DIMMs are used.-->
+ <param name="number_ranks" value="2"/>
+ <param name="num_banks_of_DRAM_chip" value="6"/>
+ <param name="Block_width_of_DRAM_chip" value="64"/> <!-- B -->
+ <param name="output_width_of_DRAM_chip" value="8"/>
+ <!--number of Dram_chips_per_rank=" 72/output_width_of_DRAM_chip-->
+ <!--number of Dram_chips_per_rank=" 72/output_width_of_DRAM_chip-->
+ <param name="page_size_of_DRAM_chip" value="8"/> <!-- 8 or 16 -->
+ <param name="burstlength_of_DRAM_chip" value="8"/>
+ <stat name="memory_accesses" value="1052"/>
+ <stat name="memory_reads" value="1052"/>
+ <stat name="memory_writes" value="1052"/>
+ </component>
+ <component id="system.mc" name="mc">
+ <!-- Memeory controllers are for DDR(2,3...) DIMMs -->
+ <!-- current version of McPAT uses published values for base parameters of memory controller
+ improvments on MC will be added in later versions. -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="mc_clock" value="1848"/><!--DIMM IO bus clock rate MHz DDR2-400 for Niagara 1-->
+ <param name="peak_transfer_rate" value="29568"/><!--MB/S Syed: GTX 470 has 177.4GB/s mem transfer rate with 6 MCs -->
+ <param name="block_size" value="64"/><!--B-->
+ <param name="number_mcs" value="6"/><!-- 6 GDDR5 memory controllers -->
+ <!-- current McPAT only supports homogeneous memory controllers -->
+ <param name="memory_channels_per_mc" value="2"/>
+ <param name="number_ranks" value="1"/>
+ <param name="withPHY" value="0"/>
+ <!-- # of ranks of each channel-->
+ <param name="req_window_size_per_channel" value="16"/>
+ <param name="IO_buffer_size_per_channel" value="16"/>
+ <param name="databus_width" value="32"/>
+ <param name="addressbus_width" value="32"/>
+ <param name="PRT_entries" value="32"/>
+ <!-- # of empirical DRAM model parameter -->
+ <param name="dram_cmd_coeff" value="0"/>
+ <param name="dram_act_coeff" value="0"/>
+ <param name="dram_nop_coeff" value="0"/>
+ <param name="dram_activity_coeff" value="0"/>
+ <param name="dram_pre_coeff" value="3.8475e-8f"/>
+ <param name="dram_rd_coeff" value="7.74707143e-8f"/>
+ <param name="dram_wr_coeff" value="3.54664286e-8f"/>
+ <param name="dram_req_coeff" value="0"/>
+ <param name="dram_const_coeff" value="0"/>
+
+ <!-- McPAT will add the control bus width to the addressbus width automatically -->
+ <stat name="memory_accesses" value="memory_accesses_match_mcpat"/>
+ <stat name="memory_reads" value="memory_reads_match_mcpat"/>
+ <stat name="memory_writes" value="memory_writes_match_mcpat"/>
+ <!-- McPAT does not track individual mc, instead, it takes the total accesses and calculate
+ the average power per MC or per channel. This is sufficent for most application.
+ Further trackdown can be easily added in later versions. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.niu" name="niu">
+ <!-- On chip 10Gb Ethernet NIC, including XAUI Phy and MAC controller -->
+ <!-- For a minimum IP packet size of 84B at 10Gb/s, a new packet arrives every 67.2ns.
+ the low bound of clock rate of a 10Gb MAC is 150Mhz -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="clockrate" value="350"/>
+ <param name="number_units" value="0"/> <!-- unlike PCIe and memory controllers, each Ethernet controller only have one port -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- ratio of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual nic, instead, it takes the total accesses and calculate
+ the average power per nic or per channel. This is sufficent for most application. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.pcie" name="pcie">
+ <!-- On chip PCIe controller, including Phy-->
+ <!-- For a minimum PCIe packet size of 84B at 8Gb/s per lane (PCIe 3.0), a new packet arrives every 84ns.
+ the low bound of clock rate of a PCIe per lane logic is 120Mhz -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="withPHY" value="1"/>
+ <param name="clockrate" value="350"/>
+ <param name="number_units" value="0"/>
+ <param name="num_channels" value="8"/> <!-- 2 ,4 ,8 ,16 ,32 -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- Percentage of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual pcie controllers, instead, it takes the total accesses and calculate
+ the average power per pcie controller or per channel. This is sufficent for most application. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.flashc" name="flashc">
+ <param name="number_flashcs" value="0"/>
+ <param name="type" value="1"/> <!-- 1: low power; 0 high performance -->
+ <param name="withPHY" value="1"/>
+ <param name="peak_transfer_rate" value="200"/><!--Per controller sustainable reak rate MB/S -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- Percentage of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual flash controller, instead, it takes the total accesses and calculate
+ the average power per fc or per channel. This is sufficent for most application -->
+ </component>
+<!--**********************************************************************-->
+
+ </component>
+</component>
\ No newline at end of file diff --git a/configs/tested-cfgs/SM7_GV100/accelwattch_sass_sim_alt.xml b/configs/tested-cfgs/SM7_GV100/accelwattch_sass_sim_alt.xml new file mode 100644 index 0000000..9998e96 --- /dev/null +++ b/configs/tested-cfgs/SM7_GV100/accelwattch_sass_sim_alt.xml @@ -0,0 +1,613 @@ +<?xml version="1.0" ?>
+<component id="root" name="root">
+ <component id="system" name="system">
+<!-- Copyright (c) 2018-2021, Vijay Kandiah, Junrui Pan, Mahmoud Khairy, Scott Peverelle, Timothy Rogers, Tor M. Aamodt, Nikos Hardavellas
+Northwestern University, Purdue University, The University of British Columbia
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this
+ list of conditions and the following disclaimer;
+2. Redistributions in binary form must reproduce the above copyright notice,
+ this list of conditions and the following disclaimer in the documentation
+ and/or other materials provided with the distribution;
+3. Neither the names of Northwestern University, Purdue University,
+ The University of British Columbia nor the names of their contributors
+ may be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE. -->
+
+ <!-- DYNAMIC Power Activity Factors -->
+
+ <param name="TOT_INST" value="16" /> <!--Instruction Buffer Activity Factor(Total Warp Instructions)-->
+ <param name="FP_INT" value="2" /> <!--Scheduler Activity Factor(Non-Memory Warp Instructons)-->
+ <param name="IC_H" value="9.967097889" /> <!--Instruction Cache Hits -->
+ <param name="IC_M" value="9.967097889" /> <!--Instruction Cache Misses-->
+ <param name="DC_RH" value="9.382262155" /> <!--L1 Data Cache Read Hits-->
+ <param name="DC_RM" value="9.382262155" /> <!--L1 Data Cache Read Misses-->
+ <param name="DC_WH" value="9.382262155" /> <!--L1 Data Cache Write Hits-->
+ <param name="DC_WM" value="9.382262155" /> <!--L1 Data Cache Write Misses-->
+ <param name="CC_H" value="0.5" /> <!--Constant Cache Hits-->
+ <param name="CC_M" value="0.5" /> <!--Constant Cache Misses-->
+ <param name="SHRD_ACC" value="1.045696662" /> <!--Shared Memory Accesses-->
+ <param name="REG_RD" value="0.096144789" /> <!--Register Reads-->
+ <param name="REG_WR" value="0.134430479" /> <!--Register Writes-->
+ <param name="INT_ACC" value="18.18093465" /> <!--Integer ALU Accesses-->
+ <param name="FP_ACC" value="0.810674358" /> <!--FPU Accesses-->
+ <param name="DP_ACC" value="1.061592439" /> <!--Integer Accesses-->
+ <param name="INT_MUL_ACC" value="0.114254558" /> <!--Integer MUL Accesses-->
+ <param name="FP_MUL_ACC" value="0.155989373" /> <!--FP MUL Accesses-->
+ <param name="FP_SQRT_ACC" value="0.377990392" /> <!--SFU: sqrt Accesses-->
+ <param name="FP_LG_ACC" value="0.155990168" /> <!--SFU: log Accesses-->
+ <param name="FP_SIN_ACC" value="0.155991536" /> <!--SFU: sin/cos Accesses-->
+ <param name="FP_EXP_ACC" value="0.571396061" /> <!--SFU: exponent Accesses-->
+ <param name="DP_MUL_ACC" value="0.155989896" /> <!--DP MUL Accesses-->
+ <param name="TENSOR_ACC" value="1.013271823" /> <!--Tensor Accesses-->
+ <param name="TEX_ACC" value="0.167780179" /> <!--Texture Unit Accesses-->
+ <param name="MEM_RD" value="0.032236806" /> <!--DRAM Reads-->
+ <param name="MEM_WR" value="0.032236806" /> <!--DRAM Writes-->
+ <param name="MEM_PRE" value="0.032236806" /> <!--DRAM Precharge-->
+ <param name="L2_RH" value="1.175516289" /> <!--L2 Data Cache Read Hits-->
+ <param name="L2_RM" value="1.175516289" /> <!--L2 Data Cache Read Misses-->
+ <param name="L2_WH" value="1.175516289" /> <!--L2 Data Cache Write Hits-->
+ <param name="L2_WM" value="1.175516289" /> <!--L2 Data Cache Write Misses-->
+ <param name="NOC_A" value="77.25" /> <!--Interconnect Network Accesses-->
+ <param name="PIPE_A" value="0.4" /> <!--Pipeline Accesses-->
+
+ <!-- STATIC & CONSTANT Power -->
+
+ <param name="constant_power" value="32.32522272" /> <!--Constant power-->
+ <param name="idle_core_power" value="0.28279166"/> <!--Idle SM power-->
+
+ <param name="static_cat1_flane" value="15.29035866"/> <!--INT (ADD+MUL) First Lane Activation Power-->
+ <param name="static_cat1_addlane" value="0.586233603"/> <!--INT (ADD+MUL) Additional Lane Activation Power-->
+
+ <param name="static_cat2_flane" value="18.6179906"/> <!--INT+FP First Lane Activation Power-->
+ <param name="static_cat2_addlane" value="0.645228013"/> <!--INT+FP Additional Lane Activation Power-->
+
+ <param name="static_cat3_flane" value="19.10017723"/> <!--INT+FP+DP First Lane Activation Power-->
+ <param name="static_cat3_addlane" value="0.726863055"/> <!--INT+FP+DP Additional Lane Activation Power-->
+
+ <param name="static_cat4_flane" value="18.55029744"/> <!--INT+FP+SFU First Lane Activation Power-->
+ <param name="static_cat4_addlane" value="0.6099397"/> <!--INT+FP+SFU Additional Lane Activation Power-->
+
+ <param name="static_cat5_flane" value="14.74826681"/> <!--INT+FP+TEX First Lane Activation Power-->
+ <param name="static_cat5_addlane" value="0.514367937"/> <!--INT+FP+TEX Additional Lane Activation Power-->
+
+ <param name="static_cat6_flane" value="48.94875596"/> <!--INT+FP+TENSOR First Lane Activation Power-->
+ <param name="static_cat6_addlane" value="0.0"/> <!--INT+FP+TENSOR Additional Lane Activation Power-->
+
+ <param name="static_light_flane" value="1.965373811"/> <!--LIGHT_SM First Lane Activation Power-->
+ <param name="static_light_addlane" value="0.003966868"/> <!--LIGHT_SM Additional Lane Activation Power-->
+
+ <param name="static_intadd_flane" value="19.70468506"/> <!--INT ADD First Lane Activation Power-->
+ <param name="static_intadd_addlane" value="0.388578623"/> <!--INT ADD Additional Lane Activation Power-->
+
+ <param name="static_intmul_flane" value="16.64811823"/> <!--INT MUL First Lane Activation Power-->
+ <param name="static_intmul_addlane" value="0.281803166"/> <!--INT MUL Additional Lane Activation Power-->
+
+ <param name="static_geomean_flane" value="17.21745077"/> <!--GEOMEAN First Lane Activation Power-->
+ <param name="static_geomean_addlane" value="0.650630555"/> <!--GEOMEAN Additional Lane Activation Power-->
+ <param name="static_shared_flane" value="31.40965691"/> <!--Shared Memory First Lane Activation Power-->
+ <param name="static_l1_flane" value="34.79491352"/> <!--L1D First Lane Activation Power-->
+ <param name="static_l2_flane" value="17.30654755"/> <!--L2D ADD+MUL First Lane Activation Power-->
+
+
+ <!-- LEAVE BELOW UNCHANGED! These are parameters used for initial GPUWattch model left untouched -->
+
+
+ <param name="GPU_Architecture" value="1"/><!-- 0-G80; 1-Fermi; others not supported -->
+ <param name="architecture" value="1"/> <!-- fermi:1 quadro:2 other: undefined-->
+ <param name="number_of_L1Directories" value="0"/>
+ <param name="number_of_L2Directories" value="0"/>
+ <param name="number_of_L2s" value="1"/> <!-- This number means how many L2 clusters in each cluster there can be multiple banks/ports -->
+ <param name="number_of_L3s" value="0"/> <!-- This number means how many L3 clusters -->
+ <param name="number_of_NoCs" value="1"/>
+ <param name="homogeneous_cores" value="1"/><!--1 means homo -->
+ <param name="homogeneous_L2s" value="1"/>
+ <param name="homogeneous_L1Directorys" value="1"/>
+ <param name="homogeneous_L2Directorys" value="1"/>
+ <param name="homogeneous_L3s" value="1"/>
+ <param name="homogeneous_ccs" value="1"/><!--cache coherece hardware -->
+ <param name="homogeneous_NoCs" value="1"/>
+ <param name="core_tech_node" value="23"/><!-- nm -->
+
+ <param name="number_cache_levels" value="2"/>
+ <param name="interconnect_projection_type" value="0"/><!--0: agressive wire technology; 1: conservative wire technology -->
+ <param name="device_type" value="0"/><!--0: HP(High Performance Type); 1: LSTP(Low standby power) 2: LOP (Low Operating Power) -->
+ <param name="longer_channel_device" value="1"/><!-- 0 no use; 1 use when possible -->
+ <param name="machine_bits" value="32"/>
+ <param name="virtual_address_width" value="32"/>
+ <param name="physical_address_width" value="32"/>
+ <param name="virtual_memory_page_size" value="4096"/>
+
+ <param name="IDLE_CORE_N" value="1"/>
+ <stat name="num_idle_cores" value="0"/><!-- Average Number of idle cores during this period -->
+ <stat name="total_cycles" value="total_cycles_match_mcpat"/>
+ <stat name="idle_cycles" value="idle_cycles_match_mcpat"/>
+ <stat name="busy_cycles" value="busy_cycles_match_mcpat"/>
+ <!--This page size(B) is complete different from the page size in Main memo secction. this page size is the size of
+ virtual memory from OS/Archi perspective; the page size in Main memo secction is the actuall physical line in a DRAM bank -->
+ <!-- *********************** cores ******************* -->
+ <component id="system.core0" name="core0">
+ <!-- Core property -->
+ <param name="clock_rate" value="700"/>
+ <param name="instruction_length" value="32"/>
+ <param name="opcode_width" value="9"/>
+ <!-- address width determins the tag_width in Cache, LSQ and buffers in cache controller
+ default value is machine_bits, if not set -->
+ <param name="machine_type" value="1"/><!-- 1 inorder; 0 OOO-->
+ <!-- inorder/OoO -->
+ <param name="number_hardware_threads" value="32"/>
+ <!-- number_instruction_fetch_ports(icache ports) is always 1 in single-thread processor,
+ it only may be more than one in SMT processors. BTB ports always equals to fetch ports since
+ branch information in consective branch instructions in the same fetch group can be read out from BTB once.-->
+ <param name="fetch_width" value="1"/>
+ <!-- fetch_width determins the size of cachelines of L1 cache block -->
+ <param name="number_instruction_fetch_ports" value="1"/>
+ <param name="decode_width" value="1"/>
+ <!-- decode_width determins the number of ports of the
+ renaming table (both RAM and CAM) scheme -->
+ <param name="issue_width" value="2"/>
+ <!-- issue_width determins the number of ports of Issue window and other logic
+ as in the complexity effective proccessors paper; issue_width==dispatch_width -->
+ <param name="commit_width" value="2"/>
+ <!-- commit_width determins the number of ports of register files -->
+ <param name="fp_issue_width" value="1"/>
+ <param name="prediction_width" value="0"/>
+ <!-- number of branch instructions can be predicted simultannouesl-->
+ <!-- Current version of McPAT does not distinguish int and floating point pipelines
+ Theses parameters are reserved for future use.-->
+ <param name="pipelines_per_core" value="1,1"/>
+ <!--integer_pipeline and floating_pipelines, if the floating_pipelines is 0, then the pipeline is shared-->
+ <param name="pipeline_depth" value="8,8"/>
+ <!-- pipeline depth of int and fp, if pipeline is shared, the second number is the average cycles of fp ops -->
+ <!-- issue and exe unit-->
+ <param name="ALU_per_core" value="32"/>
+ <!-- contains an adder, a shifter, and a logical unit -->
+ <param name="MUL_per_core" value="4"/>
+ <!-- For MUL and Div -->
+ <param name="FPU_per_core" value="32"/>
+ <!-- buffer between IF and ID stage -->
+ <param name="instruction_buffer_size" value="1"/>
+ <!-- buffer between ID and sche/exe stage -->
+ <param name="decoded_stream_buffer_size" value="1"/>
+ <param name="instruction_window_scheme" value="0"/><!-- 0 PHYREG based, 1 RSBASED-->
+ <!-- McPAT support 2 types of OoO cores, RS based and physical reg based-->
+ <param name="instruction_window_size" value="1"/>
+ <param name="fp_instruction_window_size" value="1"/>
+ <!-- the instruction issue Q as in Alpha 21264; The RS as in Intel P6 -->
+ <param name="ROB_size" value="0"/>
+ <!-- each in-flight instruction has an entry in ROB -->
+ <!-- registers -->
+ <!-- SM parameters Added by Syed Gilani -->
+ <param name="rf_banks" value="32"/>
+ <param name="simd_width" value="32"/>
+ <param name="collector_units" value="32"/>
+ <param name="core_clock_ratio" value="2"/>
+ <param name="warp_size" value="32"/>
+
+ <param name="archi_Regs_IRF_size" value="65536"/>
+ <param name="archi_Regs_FRF_size" value="32"/>
+ <!-- if OoO processor, phy_reg number is needed for renaming logic,
+ renaming logic is for both integer and floating point insts. -->
+ <param name="phy_Regs_IRF_size" value="32"/>
+ <param name="phy_Regs_FRF_size" value="32"/>
+ <!-- rename logic -->
+ <param name="rename_scheme" value="0"/>
+ <!-- can be RAM based(0) or CAM based(1) rename scheme
+ RAM-based scheme will have free list, status table;
+ CAM-based scheme have the valid bit in the data field of the CAM
+ both RAM and CAM need RAM-based checkpoint table, checkpoint_depth=# of in_flight instructions;
+ Detailed RAT Implementation see TR -->
+ <param name="register_windows_size" value="0"/>
+ <!-- how many windows in the windowed register file, sun processors;
+ no register windowing is used when this number is 0 -->
+ <!-- In OoO cores, loads and stores can be issued whether inorder(Pentium Pro) or (OoO)out-of-order(Alpha),
+ They will always try to exeute out-of-order though. -->
+ <param name="LSU_order" value="inorder"/>
+ <param name="store_buffer_size" value="32"/>
+ <!-- By default, in-order cores do not have load buffers -->
+ <param name="load_buffer_size" value="32"/>
+ <!-- number of ports refer to sustainable concurrent memory accesses -->
+ <param name="memory_ports" value="2"/>
+ <!-- max_allowed_in_flight_memo_instructions determins the # of ports of load and store buffer
+ as well as the ports of Dcache which is connected to LSU -->
+ <!-- dual-pumped Dcache can be used to save the extra read/write ports -->
+ <param name="RAS_size" value="1"/>
+ <!-- general stats, defines simulation periods;require total, idle, and busy cycles for senity check -->
+ <!-- please note: if target architecture is X86, then all the instrucions refer to (fused) micro-ops -->
+ <stat name="total_instructions" value="total_instructions_match_mcpat"/>
+ <stat name="int_instructions" value="int_instruction_match_mcpat"/>
+ <stat name="fp_instructions" value="flt_instruction_match_mcpat"/>
+ <stat name="branch_instructions" value="branch_instruction_match_mcpat"/>
+ <stat name="branch_mispredictions" value="0"/>
+ <stat name="load_instructions" value="load_instruction_match_mcpat"/>
+ <stat name="store_instructions" value="store_instruction_match_mcpat"/>
+ <stat name="committed_instructions" value="total_instructions_match_mcpat"/>
+ <stat name="committed_int_instructions" value="int_instruction_match_mcpat"/>
+ <stat name="committed_fp_instructions" value="flt_instruction_match_mcpat"/>
+ <stat name="pipeline_duty_cycle" value="0.6"/><!--<=1, runtime_ipc/peak_ipc; averaged for all cores if homogenous -->
+ <!-- the following cycle stats are used for heterogeneouse cores only,
+ please ignore them if homogeneouse cores -->
+ <stat name="total_cycles" value="total_cycles_match_mcpat"/>
+ <stat name="idle_cycles" value="idle_cycles_match_mcpat"/>
+ <stat name="busy_cycles" value="busy_cycles_match_mcpat"/>
+ <!-- instruction buffer stats -->
+ <!-- ROB stats, both RS and Phy based OoOs have ROB
+ performance simulator should capture the difference on accesses,
+ otherwise, McPAT has to guess based on number of commited instructions. -->
+ <stat name="ROB_reads" value="263886"/>
+ <stat name="ROB_writes" value="263886"/>
+ <!-- RAT accesses -->
+ <stat name="rename_accesses" value="263886"/>
+ <stat name="fp_rename_accesses" value="263886"/>
+ <!-- decode and rename stage use this, should be total ic - nop -->
+ <!-- Inst window stats -->
+ <stat name="inst_window_reads" value="263886"/>
+ <stat name="inst_window_writes" value="263886"/>
+ <stat name="inst_window_wakeup_accesses" value="263886"/>
+ <stat name="fp_inst_window_reads" value="263886"/>
+ <stat name="fp_inst_window_writes" value="263886"/>
+ <stat name="fp_inst_window_wakeup_accesses" value="263886"/>
+ <!-- RF accesses -->
+ <stat name="int_regfile_reads" value="int_register_read_access_match_mcpat"/>
+ <stat name="float_regfile_reads" value="int_register_write_access_match_mcpat"/>
+ <stat name="int_regfile_writes" value="float_register_read_access_match_mcpat"/>
+ <stat name="float_regfile_writes" value="float_register_write_access_match_mcpat"/>
+
+ <!-- The following stat is for operand collector power - Added by Syed -->
+ <stat name="non_rf_operands" value="0"/>
+
+ <!-- accesses to the working reg -->
+ <stat name="function_calls" value="0"/>
+ <stat name="context_switches" value="0"/> <!--not used in the McPAT -->
+ <!-- Number of Windowes switches (number of function calls and returns)-->
+ <!-- Alu stats by default, the processor has one FPU that includes the divider and
+ multiplier. The fpu accesses should include accesses to multiplier and divider -->
+ <stat name="ialu_accesses" value="ialu_accesses_match_mcpat"/>
+ <stat name="fpu_accesses" value="fpu_accesses_match_mcpat"/>
+ <stat name="mul_accesses" value="mul_accesses_match_mcpat"/>
+ <stat name="cdb_alu_accesses" value="0"/>
+ <stat name="cdb_mul_accesses" value="0"/>
+ <stat name="cdb_fpu_accesses" value="0"/>
+ <!-- multiple cycle accesses should be counted multiple times,
+ otherwise, McPAT can use internal counter for different floating point instructions
+ to get final accesses. But that needs detailed info for floating point inst mix -->
+ <!-- currently the performance simulator should
+ make sure all the numbers are final numbers,
+ including the explicit read/write accesses,
+ and the implicite accesses such as replacements and etc.
+ Future versions of McPAT may be able to reason the implicite access
+ based on param and stats of last level cache
+ The same rule applies to all cache access stats too! -->
+ <!-- following is AF for max power computation.
+ Do not change them, unless you understand them-->
+ <stat name="IFU_duty_cycle" value="0.25"/>
+ <stat name="LSU_duty_cycle" value="0.25"/>
+ <stat name="MemManU_I_duty_cycle" value="1"/>
+ <stat name="MemManU_D_duty_cycle" value="0.25"/>
+ <stat name="ALU_duty_cycle" value="0.9"/>
+ <stat name="MUL_duty_cycle" value="0.5"/>
+ <stat name="FPU_duty_cycle" value="1"/><!-- FPU numbers are already average -->
+ <stat name="ALU_cdb_duty_cycle" value="0.9"/>
+ <stat name="MUL_cdb_duty_cycle" value="0.5"/>
+ <stat name="FPU_cdb_duty_cycle" value="15"/>
+ <component id="system.core0.predictor" name="PBT">
+ <!-- branch predictor; tournament predictor see Alpha implementation -->
+ <param name="local_predictor_size" value="10,3"/>
+ <param name="local_predictor_entries" value="1024"/>
+ <param name="global_predictor_entries" value="4096"/>
+ <param name="global_predictor_bits" value="2"/>
+ <param name="chooser_predictor_entries" value="4096"/>
+ <param name="chooser_predictor_bits" value="2"/>
+ <!-- These parameters can be combined like below in next version
+ <param name="load_predictor" value="10,3,1024"/>
+ <param name="global_predictor" value="4096,2"/>
+ <param name="predictor_chooser" value="4096,2"/>
+ -->
+ </component>
+ <component id="system.core0.itlb" name="itlb">
+ <param name="number_entries" value="1"/>
+ <stat name="total_accesses" value="0"/>
+ <stat name="total_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <!-- there is no write requests to itlb although writes happen to itlb after miss,
+ which is actually a replacement -->
+ </component>
+ <component id="system.core0.icache" name="icache">
+ <!-- there is no write requests to itlb although writes happen to it after miss,
+ which is actually a replacement -->
+ <param name="icache_config" value="16384,128,4,1,1,3,8,0"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <!-- cache_policy;//0 no write or write-though with non-write allocate;1 write-back with write-allocate -->
+ <param name="buffer_sizes" value="16, 16, 16,0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="total_instructions_match_mcpat"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.dtlb" name="dtlb">
+ <param name="number_entries" value="1"/>
+ <stat name="total_accesses" value="0"/>
+ <stat name="total_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.ccache" name="ccache">
+ <!-- all the buffer related are optional -->
+ <param name="ccache_config" value="16384,64,2,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="ccache_read_accesses_match_mcpat"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="ccache_read_misses_match_mcpat"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.tcache" name="tcache">
+ <!-- all the buffer related are optional -->
+ <param name="tcache_config" value="49152,128,8,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="tcache_read_accesses_match_mcpat"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="tcache_read_misses_match_mcpat"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <!--model the shared memory by mimicing dcache-->
+ <component id="system.core0.sharedmemory" name="sharedmemory">
+ <!-- all the buffer related are optional -->
+ <param name="sharedmemory_config" value="98304,16,1,16,1,3,16,0"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="sharedmemory_read_access_match_mcpat"/>
+ <stat name="write_accesses" value="sharedmemory_write_access_match_mcpat"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.dcache" name="dcache">
+ <!-- all the buffer related are optional -->
+ <param name="dcache_config" value="16384,32,4,1,1,3,8,0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 0"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="dcache_read_access_match_mcpat"/>
+ <stat name="write_accesses" value="dcache_write_access_match_mcpat"/>
+ <stat name="read_misses" value="dcache_read_miss_match_mcpat"/>
+ <stat name="write_misses" value="dcache_write_miss_match_mcpat"/>
+ <stat name="conflicts" value="0"/>
+ </component>
+ <component id="system.core0.BTB" name="BTB">
+ <!-- all the buffer related are optional -->
+ <param name="BTB_config" value="8192,4,2,1, 1,3"/>
+ <!-- the parameters are capacity,block_width,associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ </component>
+ </component>
+ <component id="system.L1Directory0" name="L1Directory0">
+ <param name="Directory_type" value="0"/>
+ <!--0 cam based shadowed tag. 1 directory cache -->
+ <param name="Dir_config" value="2048,1,0,1, 4, 4,8"/>
+ <!-- the parameters are capacity,block_width, associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ <param name="buffer_sizes" value="8, 8, 8, 8"/>
+ <!-- all the buffer related are optional -->
+ <param name="clockrate" value="1400"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw search ports -->
+ <param name="device_type" value="0"/>
+ <!-- altough there are multiple access types,
+ Performance simulator needs to cast them into reads or writes
+ e.g. the invalidates can be considered as writes -->
+ <stat name="read_accesses" value="800000"/>
+ <stat name="write_accesses" value="27276"/>
+ <stat name="read_misses" value="1632"/>
+ <stat name="write_misses" value="183"/>
+ <stat name="conflicts" value="20"/>
+ <stat name="duty_cycle" value="0.45"/>
+ </component>
+ <component id="system.L2Directory0" name="L2Directory0">
+ <param name="Directory_type" value="1"/>
+ <!--0 cam based shadowed tag. 1 directory cache -->
+ <param name="Dir_config" value="1048576,16,16,1,2, 100"/>
+ <!-- the parameters are capacity,block_width, associativity,bank, throughput w.r.t. core clock, latency w.r.t. core clock,-->
+ <param name="buffer_sizes" value="8, 8, 8, 8"/>
+ <!-- all the buffer related are optional -->
+ <param name="clockrate" value="1400"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw search ports -->
+ <param name="device_type" value="0"/>
+ <!-- altough there are multiple access types,
+ Performance simulator needs to cast them into reads or writes
+ e.g. the invalidates can be considered as writes -->
+ <stat name="read_accesses" value="0"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.45"/>
+ </component>
+ <component id="system.L20" name="L20">
+ <!-- all the buffer related are optional -->
+ <param name="L2_config" value="131072,128,16,1, 4,23, 64, 1"/>
+ <!-- consider 4-way bank interleaving for Niagara 1 -->
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <param name="clockrate" value="2962"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw ports -->
+ <param name="device_type" value="0"/>
+ <stat name="read_accesses" value="200000"/>
+ <stat name="write_accesses" value="0"/>
+ <stat name="read_misses" value="0"/>
+ <stat name="write_misses" value="0"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.5"/>
+ </component>
+
+<!--**********************************************************************-->
+<component id="system.L30" name="L30">
+ <param name="L3_config" value="1048576,64,16,1, 2,100, 64,1"/>
+ <!-- the parameters are capacity,block_width, associativity, bank, throughput w.r.t. core clock, latency w.r.t. core clock,output_width, cache policy -->
+ <param name="clockrate" value="3500"/>
+ <param name="ports" value="1,1,1"/>
+ <!-- number of r, w, and rw ports -->
+ <param name="device_type" value="0"/>
+ <param name="buffer_sizes" value="16, 16, 16, 16"/>
+ <!-- cache controller buffer sizes: miss_buffer_size(MSHR),fill_buffer_size,prefetch_buffer_size,wb_buffer_size-->
+ <stat name="read_accesses" value="58824"/>
+ <stat name="write_accesses" value="27276"/>
+ <stat name="read_misses" value="1632"/>
+ <stat name="write_misses" value="183"/>
+ <stat name="conflicts" value="0"/>
+ <stat name="duty_cycle" value="0.35"/>
+ </component>
+
+
+<!--**********************************************************************-->
+ <component id="system.NoC0" name="noc0">
+ <param name="clockrate" value="700"/>
+ <param name="type" value="1"/>
+ <!-- 1 NoC, O bus -->
+ <param name="horizontal_nodes" value="2"/>
+ <param name="vertical_nodes" value="1"/>
+ <param name="has_global_link" value="0"/>
+ <!-- 1 has global link, 0 does not have global link -->
+ <param name="link_throughput" value="1"/><!--w.r.t clock -->
+ <param name="link_latency" value="1"/><!--w.r.t clock -->
+ <!-- througput >= latency -->
+ <!-- Router architecture -->
+ <param name="input_ports" value="6"/>
+ <param name="output_ports" value="6"/>
+ <param name="virtual_channel_per_port" value="1"/>
+ <!-- input buffer; in classic routers only input ports need buffers -->
+ <param name="flit_bits" value="32"/>
+ <param name="input_buffer_entries_per_vc" value="1"/><!--VCs within the same ports share input buffers whose size is propotional to the number of VCs-->
+ <param name="chip_coverage" value="1"/>
+ <!-- When multiple NOC present, one NOC will cover part of the whole chip. chip_coverage <=1 -->
+ <stat name="total_accesses" value="0"/>
+ <!-- This is the number of total accesses within the whole network not for each router -->
+ <stat name="duty_cycle" value="0.6"/>
+ </component>
+<!--**********************************************************************-->
+<!--**********************************************************************-->
+
+ <component id="system.mem" name="mem">
+ <!-- Main memory property -->
+ <param name="mem_tech_node" value="23"/>
+ <param name="device_clock" value="200"/><!--MHz, this is clock rate of the actual memory device, not the FSB -->
+ <param name="peak_transfer_rate" value="3200"/><!--MB/S-->
+ <param name="internal_prefetch_of_DRAM_chip" value="4"/>
+ <!-- 2 for DDR, 4 for DDR2, 8 for DDR3...-->
+ <!-- the device clock, peak_transfer_rate, and the internal prefetch decide the DIMM property -->
+ <!-- above numbers can be easily found from Wikipedia -->
+ <param name="capacity_per_channel" value="4096"/> <!-- MB -->
+ <!-- capacity_per_Dram_chip=capacity_per_channel/number_of_dimms/number_ranks/Dram_chips_per_rank
+ Current McPAT assumes single DIMMs are used.-->
+ <param name="number_ranks" value="2"/>
+ <param name="num_banks_of_DRAM_chip" value="6"/>
+ <param name="Block_width_of_DRAM_chip" value="64"/> <!-- B -->
+ <param name="output_width_of_DRAM_chip" value="8"/>
+ <!--number of Dram_chips_per_rank=" 72/output_width_of_DRAM_chip-->
+ <!--number of Dram_chips_per_rank=" 72/output_width_of_DRAM_chip-->
+ <param name="page_size_of_DRAM_chip" value="8"/> <!-- 8 or 16 -->
+ <param name="burstlength_of_DRAM_chip" value="8"/>
+ <stat name="memory_accesses" value="1052"/>
+ <stat name="memory_reads" value="1052"/>
+ <stat name="memory_writes" value="1052"/>
+ </component>
+ <component id="system.mc" name="mc">
+ <!-- Memeory controllers are for DDR(2,3...) DIMMs -->
+ <!-- current version of McPAT uses published values for base parameters of memory controller
+ improvments on MC will be added in later versions. -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="mc_clock" value="1848"/><!--DIMM IO bus clock rate MHz DDR2-400 for Niagara 1-->
+ <param name="peak_transfer_rate" value="29568"/><!--MB/S Syed: GTX 470 has 177.4GB/s mem transfer rate with 6 MCs -->
+ <param name="block_size" value="64"/><!--B-->
+ <param name="number_mcs" value="6"/><!-- 6 GDDR5 memory controllers -->
+ <!-- current McPAT only supports homogeneous memory controllers -->
+ <param name="memory_channels_per_mc" value="2"/>
+ <param name="number_ranks" value="1"/>
+ <param name="withPHY" value="0"/>
+ <!-- # of ranks of each channel-->
+ <param name="req_window_size_per_channel" value="16"/>
+ <param name="IO_buffer_size_per_channel" value="16"/>
+ <param name="databus_width" value="32"/>
+ <param name="addressbus_width" value="32"/>
+ <param name="PRT_entries" value="32"/>
+ <!-- # of empirical DRAM model parameter -->
+ <param name="dram_cmd_coeff" value="0"/>
+ <param name="dram_act_coeff" value="0"/>
+ <param name="dram_nop_coeff" value="0"/>
+ <param name="dram_activity_coeff" value="0"/>
+ <param name="dram_pre_coeff" value="3.8475e-8f"/>
+ <param name="dram_rd_coeff" value="7.74707143e-8f"/>
+ <param name="dram_wr_coeff" value="3.54664286e-8f"/>
+ <param name="dram_req_coeff" value="0"/>
+ <param name="dram_const_coeff" value="0"/>
+
+ <!-- McPAT will add the control bus width to the addressbus width automatically -->
+ <stat name="memory_accesses" value="memory_accesses_match_mcpat"/>
+ <stat name="memory_reads" value="memory_reads_match_mcpat"/>
+ <stat name="memory_writes" value="memory_writes_match_mcpat"/>
+ <!-- McPAT does not track individual mc, instead, it takes the total accesses and calculate
+ the average power per MC or per channel. This is sufficent for most application.
+ Further trackdown can be easily added in later versions. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.niu" name="niu">
+ <!-- On chip 10Gb Ethernet NIC, including XAUI Phy and MAC controller -->
+ <!-- For a minimum IP packet size of 84B at 10Gb/s, a new packet arrives every 67.2ns.
+ the low bound of clock rate of a 10Gb MAC is 150Mhz -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="clockrate" value="350"/>
+ <param name="number_units" value="0"/> <!-- unlike PCIe and memory controllers, each Ethernet controller only have one port -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- ratio of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual nic, instead, it takes the total accesses and calculate
+ the average power per nic or per channel. This is sufficent for most application. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.pcie" name="pcie">
+ <!-- On chip PCIe controller, including Phy-->
+ <!-- For a minimum PCIe packet size of 84B at 8Gb/s per lane (PCIe 3.0), a new packet arrives every 84ns.
+ the low bound of clock rate of a PCIe per lane logic is 120Mhz -->
+ <param name="type" value="0"/> <!-- 1: low power; 0 high performance -->
+ <param name="withPHY" value="1"/>
+ <param name="clockrate" value="350"/>
+ <param name="number_units" value="0"/>
+ <param name="num_channels" value="8"/> <!-- 2 ,4 ,8 ,16 ,32 -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- Percentage of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual pcie controllers, instead, it takes the total accesses and calculate
+ the average power per pcie controller or per channel. This is sufficent for most application. -->
+ </component>
+<!--**********************************************************************-->
+ <component id="system.flashc" name="flashc">
+ <param name="number_flashcs" value="0"/>
+ <param name="type" value="1"/> <!-- 1: low power; 0 high performance -->
+ <param name="withPHY" value="1"/>
+ <param name="peak_transfer_rate" value="200"/><!--Per controller sustainable reak rate MB/S -->
+ <stat name="duty_cycle" value="1.0"/> <!-- achievable max load <= 1.0 -->
+ <stat name="total_load_perc" value="0.7"/> <!-- Percentage of total achived load to total achivable bandwidth -->
+ <!-- McPAT does not track individual flash controller, instead, it takes the total accesses and calculate
+ the average power per fc or per channel. This is sufficent for most application -->
+ </component>
+<!--**********************************************************************-->
+
+ </component>
+</component>
\ No newline at end of file diff --git a/configs/tested-cfgs/SM7_GV100/config_volta_islip.icnt b/configs/tested-cfgs/SM7_GV100/config_volta_islip.icnt new file mode 100644 index 0000000..5ad7ecd --- /dev/null +++ b/configs/tested-cfgs/SM7_GV100/config_volta_islip.icnt @@ -0,0 +1,74 @@ +//21*1 fly with 32 flits per packet under gpgpusim injection mode +use_map = 0; +flit_size = 40; + +// currently we do not use this, see subnets below +network_count = 2; + +// Topology +topology = fly; +k = 144; +n = 1; + +// Routing + +routing_function = dest_tag; + + +// Flow control + +num_vcs = 1; +vc_buf_size = 256; +input_buffer_size = 256; +ejection_buffer_size = 256; +boundary_buffer_size = 256; + +wait_for_tail_credit = 0; + +// Router architecture + +vc_allocator = islip; //separable_input_first; +sw_allocator = islip; //separable_input_first; +alloc_iters = 1; + +credit_delay = 0; +routing_delay = 0; +vc_alloc_delay = 1; +sw_alloc_delay = 1; + +input_speedup = 1; +output_speedup = 1; +internal_speedup = 2.0; + +// Traffic, GPGPU-Sim does not use this + +traffic = uniform; +packet_size ={{1,2,3,4},{10,20}}; +packet_size_rate={{1,1,1,1},{2,1}}; + +// Simulation - Don't change + +sim_type = gpgpusim; +//sim_type = latency; +injection_rate = 0.1; + +subnets = 2; + +// Always use read and write no matter following line +//use_read_write = 1; + + +read_request_subnet = 0; +read_reply_subnet = 1; +write_request_subnet = 0; +write_reply_subnet = 1; + +read_request_begin_vc = 0; +read_request_end_vc = 0; +write_request_begin_vc = 0; +write_request_end_vc = 0; +read_reply_begin_vc = 0; +read_reply_end_vc = 0; +write_reply_begin_vc = 0; +write_reply_end_vc = 0; + diff --git a/configs/tested-cfgs/SM7_GV100/gpgpusim.config b/configs/tested-cfgs/SM7_GV100/gpgpusim.config new file mode 100644 index 0000000..26ce0eb --- /dev/null +++ b/configs/tested-cfgs/SM7_GV100/gpgpusim.config @@ -0,0 +1,237 @@ +# Copyright (c) 2018-2021, Vijay Kandiah, Junrui Pan, Mahmoud Khairy, Scott Peverelle, Timothy Rogers, Tor M. Aamodt, Nikos Hardavellas +# Northwestern University, Purdue University, The University of British Columbia +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: + +# 1. Redistributions of source code must retain the above copyright notice, this +# list of conditions and the following disclaimer; +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution; +# 3. Neither the names of Northwestern University, Purdue University, +# The University of British Columbia nor the names of their contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + + +# This config models the Volta Quadro V100 +# For more info about volta architecture: +# http://images.nvidia.com/content/volta-architecture/pdf/volta-architecture-whitepaper.pdf +# https://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=8344474&tag=1# +# http://on-demand.gputechconf.com/gtc/2018/presentation/s8122-dissecting-the-volta-gpu-architecture-through-microbenchmarking.pdf +# https://en.wikipedia.org/wiki/Volta_(microarchitecture) +# https://www.hotchips.org/wp-content/uploads/hc_archives/hc29/HC29.21-Monday-Pub/HC29.21.10-GPU-Gaming-Pub/HC29.21.132-Volta-Choquette-NVIDIA-Final3.pdf +# https://devblogs.nvidia.com/inside-volta/ +# http://on-demand.gputechconf.com/gtc/2017/presentation/s7798-luke-durant-inside-volta.pdf + +# functional simulator specification +-gpgpu_ptx_instruction_classification 0 +-gpgpu_ptx_sim_mode 0 +-gpgpu_ptx_force_max_capability 70 + +# Device Limits +-gpgpu_stack_size_limit 1024 +-gpgpu_heap_size_limit 8388608 +-gpgpu_runtime_sync_depth_limit 2 +-gpgpu_runtime_pending_launch_count_limit 2048 +-gpgpu_kernel_launch_latency 5000 +-gpgpu_TB_launch_latency 0 +-gpgpu_max_concurrent_kernel 128 + +# Compute Capability +-gpgpu_compute_capability_major 7 +-gpgpu_compute_capability_minor 0 + +# PTX execution-driven +-gpgpu_ptx_convert_to_ptxplus 0 +-gpgpu_ptx_save_converted_ptxplus 0 + +# high level architecture configuration +-gpgpu_n_clusters 80 +-gpgpu_n_cores_per_cluster 1 +-gpgpu_n_mem 32 +-gpgpu_n_sub_partition_per_mchannel 2 +-gpgpu_clock_gated_lanes 1 + +# volta clock domains +#-gpgpu_clock_domains <Core Clock>:<Interconnect Clock>:<L2 Clock>:<DRAM Clock> +-gpgpu_clock_domains 1447.0:1447.0:1447.0:850.0 +# boost mode +# -gpgpu_clock_domains 1628.0:1628.0:1628.0:850.0 + +# shader core pipeline config +-gpgpu_shader_registers 65536 +-gpgpu_registers_per_block 65536 +-gpgpu_occupancy_sm_number 70 + +# This implies a maximum of 64 warps/SM +-gpgpu_shader_core_pipeline 2048:32 +-gpgpu_shader_cta 32 +-gpgpu_simd_model 1 + +# Pipeline widths and number of FUs +# ID_OC_SP,ID_OC_DP,ID_OC_INT,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_INT,OC_EX_SFU,OC_EX_MEM,EX_WB,ID_OC_TENSOR_CORE,OC_EX_TENSOR_CORE +## Volta GV100 has 4 SP SIMD units, 4 SFU units, 4 DP units per core, 4 Tensor core units +## we need to scale the number of pipeline registers to be equal to the number of SP units +-gpgpu_pipeline_widths 4,4,4,4,4,4,4,4,4,4,8,4,4 +-gpgpu_num_sp_units 4 +-gpgpu_num_sfu_units 4 +-gpgpu_num_dp_units 4 +-gpgpu_num_int_units 4 +-gpgpu_tensor_core_avail 1 +-gpgpu_num_tensor_core_units 4 + +# Instruction latencies and initiation intervals +# "ADD,MAX,MUL,MAD,DIV" +# All Div operations are executed on SFU unit +-ptx_opcode_latency_int 4,13,4,5,145,21 +-ptx_opcode_initiation_int 2,2,2,2,8,4 +-ptx_opcode_latency_fp 4,13,4,5,39 +-ptx_opcode_initiation_fp 2,2,2,2,4 +-ptx_opcode_latency_dp 8,19,8,8,330 +-ptx_opcode_initiation_dp 4,4,4,4,130 +-ptx_opcode_latency_sfu 100 +-ptx_opcode_initiation_sfu 8 +-ptx_opcode_latency_tesnor 64 +-ptx_opcode_initiation_tensor 64 + +# Volta has sub core model, in which each scheduler has its own register file and EUs +# i.e. schedulers are isolated +-gpgpu_sub_core_model 1 +# disable specialized operand collectors and use generic operand collectors instead +-gpgpu_enable_specialized_operand_collector 0 +-gpgpu_operand_collector_num_units_gen 8 +-gpgpu_operand_collector_num_in_ports_gen 8 +-gpgpu_operand_collector_num_out_ports_gen 8 +# volta has 8 banks, 4 schedulers, two banks per scheduler +# we increase #banks to 16 to mitigate the effect of Regisrer File Cache (RFC) which we do not implement in the current version +-gpgpu_num_reg_banks 16 +-gpgpu_reg_file_port_throughput 2 + +# shared memory bankconflict detection +-gpgpu_shmem_num_banks 32 +-gpgpu_shmem_limited_broadcast 0 +-gpgpu_shmem_warp_parts 1 +-gpgpu_coalesce_arch 70 + +# Volta has four schedulers per core +-gpgpu_num_sched_per_core 4 +# Loose round robin scheduler +-gpgpu_scheduler lrr +## In Volta, a warp scheduler can issue 1 inst per cycle +-gpgpu_max_insn_issue_per_warp 1 +-gpgpu_dual_issue_diff_exec_units 1 + +## L1/shared memory configuration +# <sector?>:<nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> +# ** Optional parameter - Required when mshr_type==Texture Fifo +# Defualt config is 32KB DL1 and 96KB shared memory +# In Volta, we assign the remaining shared memory to L1 cache +# if the assigned shd mem = 0, then L1 cache = 128KB +# For more info, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x +# disable this mode in case of multi kernels/apps execution +-gpgpu_adaptive_cache_config 1 +-gpgpu_shmem_option 0,8,16,32,64,96 +-gpgpu_unified_l1d_size 128 +# L1 cache configuration +-gpgpu_l1_banks 4 +-gpgpu_cache:dl1 S:4:128:64,L:T:m:L:L,A:512:8,16:0,32 +-gpgpu_l1_cache_write_ratio 25 +-gpgpu_l1_latency 20 +-gpgpu_gmem_skip_L1D 0 +-gpgpu_flush_l1_cache 1 +-gpgpu_n_cluster_ejection_buffer_size 32 +# shared memory configuration +-gpgpu_shmem_size 98304 +-gpgpu_shmem_sizeDefault 98304 +-gpgpu_shmem_per_block 65536 +-gpgpu_smem_latency 20 + +# 32 sets, each 128 bytes 24-way for each memory sub partition (96 KB per memory sub partition). This gives us 6MB L2 cache +-gpgpu_cache:dl2 S:32:128:24,L:B:m:L:P,A:192:4,32:0,32 +-gpgpu_cache:dl2_texture_only 0 +-gpgpu_dram_partition_queues 64:64:64:64 +-gpgpu_perf_sim_memcpy 1 +-gpgpu_memory_partition_indexing 2 + +# 128 KB Inst. +-gpgpu_cache:il1 N:64:128:16,L:R:f:N:L,S:2:48,4 +-gpgpu_inst_fetch_throughput 4 +# 128 KB Tex +# Note, TEX is deprected in Volta, It is used for legacy apps only. Use L1D cache instead with .nc modifier or __ldg mehtod +-gpgpu_tex_cache:l1 N:4:128:256,L:R:m:N:L,T:512:8,128:2 +# 64 KB Const +-gpgpu_const_cache:l1 N:128:64:8,L:R:f:N:L,S:2:64,4 +-gpgpu_perfect_inst_const_cache 1 + +# interconnection +#-network_mode 1 +#-inter_config_file config_volta_islip.icnt +# use built-in local xbar +-network_mode 2 +-icnt_in_buffer_limit 512 +-icnt_out_buffer_limit 512 +-icnt_subnets 2 +-icnt_flit_size 40 +-icnt_arbiter_algo 1 + +# memory partition latency config +-gpgpu_l2_rop_latency 160 +-dram_latency 100 + +# dram model config +-gpgpu_dram_scheduler 1 +-gpgpu_frfcfs_dram_sched_queue_size 64 +-gpgpu_dram_return_queue_size 192 + +# for HBM, three stacks, 24 channles, each (128 bits) 16 bytes width +-gpgpu_n_mem_per_ctrlr 1 +-gpgpu_dram_buswidth 16 +-gpgpu_dram_burst_length 2 +-dram_data_command_freq_ratio 2 # HBM is DDR +-gpgpu_mem_address_mask 1 +-gpgpu_mem_addr_mapping dramid@8;00000000.00000000.00000000.00000000.0000RRRR.RRRRRRRR.RBBBCCCB.CCCSSSSS + +# HBM timing are adopted from hynix JESD235 standered and nVidia HPCA 2017 paper (http://www.cs.utah.edu/~nil/pubs/hpca17.pdf) +# Timing for 1 GHZ +# tRRDl and tWTR are missing, need to be added +#-gpgpu_dram_timing_opt "nbk=16:CCD=1:RRD=4:RCD=14:RAS=33:RP=14:RC=47: +# CL=14:WL=2:CDLR=3:WR=12:nbkgrp=4:CCDL=2:RTPL=4" + +# Timing for 850 MHZ, V100 HBM runs at 850 MHZ +-gpgpu_dram_timing_opt "nbk=16:CCD=1:RRD=3:RCD=12:RAS=28:RP=12:RC=40: + CL=12:WL=2:CDLR=3:WR=10:nbkgrp=4:CCDL=2:RTPL=3" + +# HBM has dual bus interface, in which it can issue two col and row commands at a time +-dram_dual_bus_interface 1 +# select lower bits for bnkgrp to increase bnkgrp parallelism +-dram_bnk_indexing_policy 0 +-dram_bnkgrp_indexing_policy 1 + +#-dram_seperate_write_queue_enable 1 +#-dram_write_queue_size 64:56:32 + +# stat collection +-gpgpu_memlatency_stat 14 +-gpgpu_runtime_stat 500 +-enable_ptx_file_line_stats 1 +-visualizer_enabled 0 + +# tracing functionality +#-trace_enabled 1 +#-trace_components WARP_SCHEDULER,SCOREBOARD +#-trace_sampling_core 0 diff --git a/configs/tested-cfgs/SM7_QV100/gpgpusim.config b/configs/tested-cfgs/SM7_QV100/gpgpusim.config index 76c99b7..b3384af 100644 --- a/configs/tested-cfgs/SM7_QV100/gpgpusim.config +++ b/configs/tested-cfgs/SM7_QV100/gpgpusim.config @@ -50,6 +50,7 @@ -gpgpu_runtime_pending_launch_count_limit 2048 -gpgpu_kernel_launch_latency 5000 -gpgpu_TB_launch_latency 0 +-gpgpu_max_concurrent_kernel 128 # Compute Capability -gpgpu_compute_capability_major 7 @@ -68,7 +69,7 @@ # volta clock domains #-gpgpu_clock_domains <Core Clock>:<Interconnect Clock>:<L2 Clock>:<DRAM Clock> --gpgpu_clock_domains 1447.0:1447.0:1447.0:850.0 +-gpgpu_clock_domains 1132.0:1132.0:1132.0:850.0 # boost mode # -gpgpu_clock_domains 1628.0:1628.0:1628.0:850.0 @@ -136,7 +137,7 @@ -gpgpu_dual_issue_diff_exec_units 1 ## L1/shared memory configuration -# <nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> +# <sector?>:<nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> # ** Optional parameter - Required when mshr_type==Texture Fifo # Defualt config is 32KB DL1 and 96KB shared memory # In Volta, we assign the remaining shared memory to L1 cache diff --git a/configs/tested-cfgs/SM7_QV100/hw_perf.csv b/configs/tested-cfgs/SM7_QV100/hw_perf.csv deleted file mode 100644 index aa88bb2..0000000 --- a/configs/tested-cfgs/SM7_QV100/hw_perf.csv +++ /dev/null @@ -1,26 +0,0 @@ -Benchmark,Kernel,L1_RH,L1_RM,L1_WH,L1_WM,CC_ACC,SHRD_ACC,DRAM_Rd,DRAM_Wr,L2_RH,L2_RM,L2_WH,L2_WM,NOC,Pipeline_Duty,Num_Idle_SMs,Elapsed_Cycles,Chip Voltage -b+tree-rodinia-3.1,findRangeK,1634256.0,561818.0,40785.0,19032.0,0.0,0.0,259346.0,3524.0,396522.0,259508.0,60000.0,0.0,1343246.0,0.3268163900773488,5.064000000000002,66542.7,1.0 -b+tree-rodinia-3.1,findK,1318908.0,525035.0,42619.0,7404.0,0.0,0.0,255317.0,2582.0,366918.0,255364.0,50000.0,0.0,1250108.0,0.2740918672650619,3.191999999999995,80883.0,1.0 -backprop-rodinia-3.1,_Z22bpnn_layerforward_CUDAPfS_S_S_ii,49152.0,143738.0,192432.0,4232.0,0.0,413696.0,147464.0,60097.0,29059.0,147460.0,196608.0,0.0,704512.0,0.5619432556155418,7.520000000000007,23324.775,1.0 -backprop-rodinia-3.1,_Z24bpnn_adjust_weights_cudaPfiS_iS_S_,465990.0,277805.0,327015.0,887.0,0.0,0.0,286738.0,190646.0,54315.0,286734.0,327686.0,0.0,1263518.0,0.20116733697224465,9.496000000000002,32578.425,1.0 -hotspot-rodinia-3.1,_Z14calculate_tempiPfS_S_iiiiffffff,4250.0,691050.0,0.0,175104.0,0.0,997428.0,262147.0,66263.0,486965.0,262144.0,175104.0,0.0,1732988.0,0.9470499252952201,3.3200000000000074,56438.825,1.0 -kmeans-rodinia-3.1,_Z11kmeansPointPfiiiPiS_S_S0_,0.0,0.0,0.0,102400.0,4352107.0,0.0,12302960.0,92472.5,6742186.0,12321532.0,102400.0,0.0,26022036.0,0.11420395712434231,1.5799999999999947,894550.775,1.0 -srad_v1-rodinia-3.1,_Z4sradfiilPiS_S_S_PfS0_S0_S0_fS0_S0_,158304.87000000002,89035.40999999999,0.0,143700.0,0.0,0.0,28986.500000000033,45424.200000000026,68135.7,28984.00000000001,143700.0,0.0,481258.2600000001,0.5320091849844065,15.272880000000004,14251.741749999997,1.0 -parboil-sad,_Z11mb_sad_calcPtS_ii,101840.0,415925.0,2102177.0,7289373.0,0.0,10033920.0,257308.0,8720433.0,8754664.0,257280.0,9390720.0,0.0,36398656.0,0.25130932753519797,0.19199999999999662,6551129.125,1.0 -parboil-sgemm,_Z9mysgemmNTPKfiS0_iPfiiff,7109956.0,2452728.0,133388.0,1284.0,0.0,8642304.0,393092.0,36894.0,2059512.0,393088.0,135168.0,0.0,5176696.0,0.5495706862295477,1.8799999999999972,358744.025,1.0 -parboil-mri-q,_Z12ComputeQ_GPUiiPfS_S_S_S_,0.0,163840.0,65184.0,154.0,17617612.5,0.0,164356.0,0.0,0.0,163840.0,65536.0,0.0,458752.0,0.5767256645623982,12.363999999999997,691892.925,1.0 -dct8x8,_Z14CUDAkernel1DCTPfiiiy,0.0,0.0,552.8,32121.9,786431.9999999999,114688.00000000001,32786.0,0.0,16383.999999999998,32767.999999999996,32767.999999999996,0.0,131071.99999999999,0.06091433507559575,7.7799999999999985,24207.632500000003,1.0 -dct8x8,_Z14CUDAkernel2DCTPfS_i,0.0,32768.00000000002,0.0,32768.00000000002,0.0,49152.00000000004,32773.25742574254,0.0,0.0,32768.00000000002,32768.00000000002,0.0,131072.0000000001,0.14345732731755537,30.750257425742568,5822.941584158416,1.0 -binomialOptions,_Z21binomialOptionsKernelv,0.0,0.0,0.0,1024.0,23688.0,16778240.0,640.0,0.0,0.0,0.0,1024.0,0.0,2048.0,0.6457304629145744,1.9519999999999982,1366301.225,1.0 -fastWalshTransform,_Z15fwtBatch2KernelPfS_i,0.0,1048576.0000000002,774120.4444444445,271536.22222222225,0.0,0.0,1048581.888888889,945003.222222222,0.0,1048576.0000000002,1048576.0000000002,0.0,4194304.000000001,0.0867005928407203,2.574222222222223,120947.73472222223,1.0 -fastWalshTransform,_Z15fwtBatch1KernelPfS_i,0.0,1048576.0,645060.0,403890.6666666666,0.0,3407872.0,1048581.0,950303.3333333333,0.0,1048576.0,1048576.0,0.0,4194304.0,0.3836524328760675,2.621333333333329,149487.8,1.0 -histogram,_Z17histogram64KernelPjP5uint4j,0.0,2097152.0,0.0,34960.0,0.0,4893504.000000001,2097184.2941176468,26959.294117647052,0.0,2097152.0,34960.0,0.0,4264223.999999999,0.3361853461559831,3.706823529411762,146480.14411764703,1.0 -mergeSort,_Z21mergeSortSharedKernelILj1EEvPjS0_S0_S0_j,0.0,1048576.0,0.0,1048576.0,0.0,12976128.0,1048580.0,950169.0,0.0,1048576.0,1048576.0,0.0,4194304.0,0.9137102229423307,1.1600000000000055,439316.525,1.0 -mergeSort,_Z30mergeElementaryIntervalsKernelILj1EEvPjS0_S0_S0_S0_S0_jj,152481.75,1127706.3333333333,439852.24999999994,829969.9166666665,0.0,3670010.1666666665,1056772.0000000002,959704.0833333334,199523.16666666666,1056768.0,1269875.1666666667,0.0,4878632.833333334,0.44812863772322986,1.6420000000000003,157457.05,1.0 -quasirandomGenerator,_Z26quasirandomGeneratorKernelPfjj,0.0,0.0,0.0,393215.9999999999,47616.000000000015,0.0,21.0,294938.38095238095,0.0,0.0,393215.9999999999,0.0,786431.9999999998,0.6109600290450061,17.68266666666667,80626.8130952381,1.0 -quasirandomGenerator,_Z16inverseCNDKernelPfPjj,0.0,0.0,0.0,393215.9999999999,0.0,0.0,5.952380952380952,294941.6666666666,0.0,0.0,393215.9999999999,0.0,786431.9999999998,0.307434624439692,5.790476190476192,58367.4988095238,1.0 -sobolQRNG,_Z15sobolGPU_kerneljjPjPf,172832.0,31976.0,0.0,1250000.0,0.0,1899700.0,405.0,1151641.0,31592.0,400.0,1250000.0,0.0,2563936.0,0.6380044567750587,2.7840000000000042,112087.775,1.0 -cutlass_perf_test_k1,_ZN7cutlass4gemm16gemm_kernel_nolbINS0_12GemmMainloopINS0_10GemmTraitsINS0_14WmmaGemmConfigILNS_12MatrixLayout4KindE1ELS6_1ENS_5ShapeILi64ELi128ELi128ELi1EEE6__halfS9_ffNS7_ILi64ELi32ELi64ELi1EEENS7_ILi16ELi16ELi16ELi1EEELi8ELi8ELi8ELi8ELi4ELi4ELi4EEENS0_16GlobalLoadStreamILNS_11GemmOperand4KindE0ENS0_20GemmGlobalIteratorAbINS0_20GemmGlobalTileTraitsILSF_0ELS6_1EKS9_NS7_ILi1ELi64ELi128ELi1EEENS7_ILi1ELi8ELi32ELi1EEELi8EEEiEENS_17TileStoreIteratorINS0_27GemmSharedStoreTileAbTraitsIS9_NS7_ILi1ELi64ELi136ELi1EEENS7_ILi1ELi16ELi16ELi1EEELi8EEES9_LNS_15IteratorAdvance4KindE1ELNS_11MemorySpace4KindE1EiS9_LNS_19FragmentElementType4KindE0ENS7_ILi0ELi0ELi0ELi0EEEEENS_4CopyINS_8FragmentIS9_Li32ELm16EEEEEEENSD_ILSF_1ENSG_INSH_ILSF_1ELS6_1ESI_NS7_ILi1ELi128ELi64ELi1EEENS7_ILi1ELi4ELi64ELi1EEELi8EEEiEENSN_INSO_IS9_NS7_ILi1ELi128ELi72ELi1EEENS7_ILi1ELi32ELi8ELi1EEELi8EEES9_LST_1ELSV_1EiS9_LSX_0ESY_EES13_EENS0_16SharedLoadStreamINS_16TileLoadIteratorINS0_29WmmaGemmSharedLoadTileATraitsILS6_1ES9_SP_NS7_ILi1ELi4ELi2ELi1EEELi16ENS7_ILi1ELi1ELi4ELi1EEENS7_ILi2176ELi0ELi32ELi0EEESB_EES9_LST_1ELSV_1EiNS_10WmmaMatrixILSF_0ELS6_1ES9_SB_EELSX_1ESY_EENS10_INS11_IS1M_Li4ELm16EEEEEEENS1E_INS1F_INS0_29WmmaGemmSharedLoadTileBTraitsILS6_1ES9_S19_S1H_Li1152ENS7_ILi1ELi1ELi2ELi1EEENS7_ILi16ELi0ELi4608ELi1EEESB_EES9_LST_1ELSV_1EiNS1L_ILSF_1ELS6_1ES9_SB_EELSX_1ESY_EENS10_INS11_IS1V_Li2ELm16EEEEEEENS0_12GemmEpilogueINS0_28SimplifiedGemmEpilogueTraitsISC_NS0_13LinearScalingIfNS0_19FragmentMultiplyAddIffLb1EEEEEiNS0_28WmmaGemmEpilogueTraitsHelperISC_fS25_iEEEEEENS0_20IdentityBlockSwizzleEiNS0_17ClearAccumulatorsIfLi1EEEEEEEEEvNT_6ParamsE,0.0,460800.0,0.0,5120.0,160.0,577120.0000000001,412167.99999999994,42.285714285714285,48640.0,412160.0,5120.0,0.0,931840.0,0.24658369358809393,60.32228571428572,139808.59999999998,1.0 -cutlass_perf_test_k2,_ZN7cutlass4gemm16gemm_kernel_nolbINS0_12GemmMainloopINS0_10GemmTraitsINS0_14WmmaGemmConfigILNS_12MatrixLayout4KindE1ELS6_1ENS_5ShapeILi64ELi128ELi128ELi1EEE6__halfS9_ffNS7_ILi64ELi32ELi64ELi1EEENS7_ILi16ELi16ELi16ELi1EEELi8ELi8ELi8ELi8ELi4ELi4ELi4EEENS0_16GlobalLoadStreamILNS_11GemmOperand4KindE0ENS0_20GemmGlobalIteratorAbINS0_20GemmGlobalTileTraitsILSF_0ELS6_1EKS9_NS7_ILi1ELi64ELi128ELi1EEENS7_ILi1ELi8ELi32ELi1EEELi8EEEiEENS_17TileStoreIteratorINS0_27GemmSharedStoreTileAbTraitsIS9_NS7_ILi1ELi64ELi136ELi1EEENS7_ILi1ELi16ELi16ELi1EEELi8EEES9_LNS_15IteratorAdvance4KindE1ELNS_11MemorySpace4KindE1EiS9_LNS_19FragmentElementType4KindE0ENS7_ILi0ELi0ELi0ELi0EEEEENS_4CopyINS_8FragmentIS9_Li32ELm16EEEEEEENSD_ILSF_1ENSG_INSH_ILSF_1ELS6_1ESI_NS7_ILi1ELi128ELi64ELi1EEENS7_ILi1ELi4ELi64ELi1EEELi8EEEiEENSN_INSO_IS9_NS7_ILi1ELi128ELi72ELi1EEENS7_ILi1ELi32ELi8ELi1EEELi8EEES9_LST_1ELSV_1EiS9_LSX_0ESY_EES13_EENS0_16SharedLoadStreamINS_16TileLoadIteratorINS0_29WmmaGemmSharedLoadTileATraitsILS6_1ES9_SP_NS7_ILi1ELi4ELi2ELi1EEELi16ENS7_ILi1ELi1ELi4ELi1EEENS7_ILi2176ELi0ELi32ELi0EEESB_EES9_LST_1ELSV_1EiNS_10WmmaMatrixILSF_0ELS6_1ES9_SB_EELSX_1ESY_EENS10_INS11_IS1M_Li4ELm16EEEEEEENS1E_INS1F_INS0_29WmmaGemmSharedLoadTileBTraitsILS6_1ES9_S19_S1H_Li1152ENS7_ILi1ELi1ELi2ELi1EEENS7_ILi16ELi0ELi4608ELi1EEESB_EES9_LST_1ELSV_1EiNS1L_ILSF_1ELS6_1ES9_SB_EELSX_1ESY_EENS10_INS11_IS1V_Li2ELm16EEEEEEENS0_12GemmEpilogueINS0_28SimplifiedGemmEpilogueTraitsISC_NS0_13LinearScalingIfNS0_19FragmentMultiplyAddIffLb1EEEEEiNS0_28WmmaGemmEpilogueTraitsHelperISC_fS25_iEEEEEENS0_20IdentityBlockSwizzleEiNS0_17ClearAccumulatorsIfLi1EEEEEEEEEvNT_6ParamsE,0.0,2097151.9999999995,171796.0,65782.85714285714,255.99999999999994,1464319.9999999998,1081352.2857142857,45.42857142857143,1015808.0000000002,1081344.0,237568.0,0.0,4669440.0,0.38530040572560803,48.440000000000005,228263.9035714286,1.0 -cutlass_perf_test_k3,_ZN7cutlass4gemm16gemm_kernel_nolbINS0_12GemmMainloopINS0_10GemmTraitsINS0_14WmmaGemmConfigILNS_12MatrixLayout4KindE1ELS6_1ENS_5ShapeILi64ELi128ELi128ELi1EEE6__halfS9_ffNS7_ILi64ELi32ELi64ELi1EEENS7_ILi16ELi16ELi16ELi1EEELi8ELi8ELi8ELi8ELi4ELi4ELi4EEENS0_16GlobalLoadStreamILNS_11GemmOperand4KindE0ENS0_20GemmGlobalIteratorAbINS0_20GemmGlobalTileTraitsILSF_0ELS6_1EKS9_NS7_ILi1ELi64ELi128ELi1EEENS7_ILi1ELi8ELi32ELi1EEELi8EEEiEENS_17TileStoreIteratorINS0_27GemmSharedStoreTileAbTraitsIS9_NS7_ILi1ELi64ELi136ELi1EEENS7_ILi1ELi16ELi16ELi1EEELi8EEES9_LNS_15IteratorAdvance4KindE1ELNS_11MemorySpace4KindE1EiS9_LNS_19FragmentElementType4KindE0ENS7_ILi0ELi0ELi0ELi0EEEEENS_4CopyINS_8FragmentIS9_Li32ELm16EEEEEEENSD_ILSF_1ENSG_INSH_ILSF_1ELS6_1ESI_NS7_ILi1ELi128ELi64ELi1EEENS7_ILi1ELi4ELi64ELi1EEELi8EEEiEENSN_INSO_IS9_NS7_ILi1ELi128ELi72ELi1EEENS7_ILi1ELi32ELi8ELi1EEELi8EEES9_LST_1ELSV_1EiS9_LSX_0ESY_EES13_EENS0_16SharedLoadStreamINS_16TileLoadIteratorINS0_29WmmaGemmSharedLoadTileATraitsILS6_1ES9_SP_NS7_ILi1ELi4ELi2ELi1EEELi16ENS7_ILi1ELi1ELi4ELi1EEENS7_ILi2176ELi0ELi32ELi0EEESB_EES9_LST_1ELSV_1EiNS_10WmmaMatrixILSF_0ELS6_1ES9_SB_EELSX_1ESY_EENS10_INS11_IS1M_Li4ELm16EEEEEEENS1E_INS1F_INS0_29WmmaGemmSharedLoadTileBTraitsILS6_1ES9_S19_S1H_Li1152ENS7_ILi1ELi1ELi2ELi1EEENS7_ILi16ELi0ELi4608ELi1EEESB_EES9_LST_1ELSV_1EiNS1L_ILSF_1ELS6_1ES9_SB_EELSX_1ESY_EENS10_INS11_IS1V_Li2ELm16EEEEEEENS0_12GemmEpilogueINS0_28SimplifiedGemmEpilogueTraitsISC_NS0_13LinearScalingIfNS0_19FragmentMultiplyAddIffLb1EEEEEiNS0_28WmmaGemmEpilogueTraitsHelperISC_fS25_iEEEEEENS0_20IdentityBlockSwizzleEiNS0_17ClearAccumulatorsIfLi1EEEEEEEEEvNT_6ParamsE,0.0,3276800.0000000005,429682.85714285716,164204.57142857142,640.0,2309120.0,491527.9999999999,77869.28571428571,2785279.9999999995,491519.99999999994,593920.0000000001,0.0,7741440.0,0.8525726478636384,1.832,161781.07857142857,1.0 -cudaTensorCoreGemm,_Z12compute_gemmPK6__halfS1_PKfPfff,0.0,69206016.0,0.0,2097152.0,0.0,30146560.0,16974052.0,1998866.0,52232060.0,16973824.0,2097152.0,0.0,142606336.0,0.7380984268363922,1.264000000000003,3871172.375,1.0 diff --git a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config index 5c6be22..c37aaf0 100644 --- a/configs/tested-cfgs/SM7_TITANV/gpgpusim.config +++ b/configs/tested-cfgs/SM7_TITANV/gpgpusim.config @@ -18,6 +18,7 @@ -gpgpu_heap_size_limit 8388608 -gpgpu_runtime_sync_depth_limit 2 -gpgpu_runtime_pending_launch_count_limit 2048 +-gpgpu_max_concurrent_kernel 128 # Compute Capability -gpgpu_compute_capability_major 7 @@ -106,7 +107,7 @@ -gpgpu_dual_issue_diff_exec_units 1 ## L1/shared memory configuration -# <nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> +# <sector?>:<nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> # ** Optional parameter - Required when mshr_type==Texture Fifo # Defualt config is 32KB DL1 and 96KB shared memory # In Volta, we assign the remaining shared memory to L1 cache diff --git a/configs/tested-cfgs/SM86_RTX3070/gpgpusim.config b/configs/tested-cfgs/SM86_RTX3070/gpgpusim.config index 8543781..d26b1a6 100644 --- a/configs/tested-cfgs/SM86_RTX3070/gpgpusim.config +++ b/configs/tested-cfgs/SM86_RTX3070/gpgpusim.config @@ -10,6 +10,7 @@ -gpgpu_runtime_pending_launch_count_limit 2048 -gpgpu_kernel_launch_latency 5000 -gpgpu_TB_launch_latency 0 +-gpgpu_max_concurrent_kernel 128 # Compute Capability -gpgpu_compute_capability_major 8 @@ -82,7 +83,7 @@ -gpgpu_dual_issue_diff_exec_units 1 ## L1/shared memory configuration -# <nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> +# <sector?>:<nsets>:<bsize>:<assoc>,<rep>:<wr>:<alloc>:<wr_alloc>:<set_index_fn>,<mshr>:<N>:<merge>,<mq>:**<fifo_entry> # ** Optional parameter - Required when mshr_type==Texture Fifo # In adaptive cache, we adaptively assign the remaining shared memory to L1 cache # For more info, see https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#shared-memory-7-x diff --git a/cuobjdump_to_ptxplus/Makefile b/cuobjdump_to_ptxplus/Makefile index e95136a..0eb7d1e 100644 --- a/cuobjdump_to_ptxplus/Makefile +++ b/cuobjdump_to_ptxplus/Makefile @@ -28,10 +28,10 @@ $(OUTPUT_DIR)/cuobjdump_to_ptxplus: $(OUTPUT_DIR)/cuobjdumpInst.o $(OUTPUT_DIR)/ $(OUTPUT_DIR)/lex.ptx_.c : ptx.l - ${LEX} ${LEXFLAGS} -o$(OUTPUT_DIR)/lex.ptx_.c ptx.l + ${LEX} ${LEXFLAGS} -o$(OUTPUT_DIR)/lex.ptx_.c ptx.l 2> /dev/null $(OUTPUT_DIR)/ptx.tab.c : ptx.y - ${YACC} ${YFLAGS} --name-prefix=ptx_ -v ptx.y --file-prefix=$(OUTPUT_DIR)/ptx + ${YACC} ${YFLAGS} --name-prefix=ptx_ -v ptx.y --file-prefix=$(OUTPUT_DIR)/ptx 2> /dev/null $(OUTPUT_DIR)/ptx.tab.h :$(OUTPUT_DIR)/ptx.tab.c diff --git a/cuobjdump_to_ptxplus/cuobjdumpInstList.cc b/cuobjdump_to_ptxplus/cuobjdumpInstList.cc index 32834c7..d42e59e 100644 --- a/cuobjdump_to_ptxplus/cuobjdumpInstList.cc +++ b/cuobjdump_to_ptxplus/cuobjdumpInstList.cc @@ -505,7 +505,7 @@ std::string cuobjdumpInstList::parseCuobjdumpRegister(std::string reg, bool lo, } else { output("ERROR: unknown register type.\n"); printf("\nERROR: unknown register type: "); - printf(reg.c_str()); + printf("%s",reg.c_str()); printf("\n"); assert(0); } diff --git a/cuobjdump_to_ptxplus/cuobjdump_to_ptxplus.cc b/cuobjdump_to_ptxplus/cuobjdump_to_ptxplus.cc index 82dcb7c..5c6fdcd 100644 --- a/cuobjdump_to_ptxplus/cuobjdump_to_ptxplus.cc +++ b/cuobjdump_to_ptxplus/cuobjdump_to_ptxplus.cc @@ -54,7 +54,7 @@ FILE *ptxplus_out; void output(const char * text) { //printf(text); - fprintf(ptxplus_out, text); + fprintf(ptxplus_out,"%s", text); } void output(const std::string text) { diff --git a/format-code.sh b/format-code.sh index ac753f0..acd33ab 100755 --- a/format-code.sh +++ b/format-code.sh @@ -1,5 +1,6 @@ # This bash script formats GPGPU-Sim using clang-format THIS_DIR="$( cd "$( dirname "$BASH_SOURCE" )" && pwd )" +echo "Running clang-format on $THIS_DIR" clang-format -i ${THIS_DIR}/libcuda/*.h clang-format -i ${THIS_DIR}/libcuda/*.cc clang-format -i ${THIS_DIR}/src/*.h diff --git a/gpgpusim_check.cmake b/gpgpusim_check.cmake new file mode 100644 index 0000000..486d66d --- /dev/null +++ b/gpgpusim_check.cmake @@ -0,0 +1,135 @@ +# Dependency checking +# Unset FindCUDA variables so that it +# gets reconfigured +include(gpgpusim_unset_cuda.cmake) + +find_package(Git REQUIRED) +find_package(BISON REQUIRED) +find_package(FLEX REQUIRED) +find_package(ZLIB REQUIRED) +find_package(CUDAToolkit REQUIRED) +find_package(Doxygen) +find_package(Python3) + +# GPGPU-Sim additional checking and info +message(CHECK_START "Additional settings for ${CMAKE_PROJECT_NAME}") +list(APPEND CMAKE_MESSAGE_INDENT " ") + +# Check for OS +message(CHECK_START "Checking for OS") +if((NOT APPLE) AND (NOT UNIX) AND (NOT LINUX)) + message(FATAL_ERROR "${CMAKE_SYSTEM_NAME} not supported") +else() + message(CHECK_PASS ${CMAKE_SYSTEM_NAME}) +endif() + +# Check for version +message(CHECK_START "Checking GPGPU-Sim version") +message(CHECK_PASS "${CMAKE_PROJECT_VERSION}") + +# Check for git commit hash +message(CHECK_START "Checking git commit hash") +# Get the latest abbreviated commit hash of the working branch +execute_process( + COMMAND git log -1 --format=%H + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + OUTPUT_VARIABLE GPGPUSIM_CONFIG_GIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE + RESULT_VARIABLE GPGPUSIM_CHECK_GIT_HASH +) +if(${GPGPUSIM_CHECK_GIT_HASH}) + message(CHECK_FAIL "not a git repo") +else() + message(CHECK_PASS "${GPGPUSIM_CONFIG_GIT_HASH}") +endif() + +# Check for compiler and version +message(CHECK_START "Checking CXX compiler") +if(NOT (${CMAKE_CXX_COMPILER_ID} STREQUAL GNU)) + message(CHECK_FAIL "GPGPU-Sim only tested with GCC: ${CMAKE_CXX_COMPILER_ID}") +else() + message(CHECK_PASS "${CMAKE_CXX_COMPILER}") +endif() +message(CHECK_START "Checking CXX compiler version") +message(CHECK_PASS "${CMAKE_CXX_COMPILER_VERSION}") +set(GPGPSIM_CC_VERSION ) + +# Check for CUDA nvcc and version +# Check already done with find_package, here just to display the path and version +message(CHECK_START "Checking CUDA compiler") +if(NOT CUDAToolkit_FOUND) + message(CHECK_FAIL "not found") +else() + message(CHECK_PASS "${CUDAToolkit_NVCC_EXECUTABLE}") + message(CHECK_START "Checking CUDA compiler version") + message(CHECK_PASS "${CUDAToolkit_VERSION}") + if((CUDAToolkit_VERSION VERSION_LESS 2.0.3) OR (CUDAToolkit_VERSION VERSION_GREATER 11.10.0)) + message(FATAL_ERROR "GPGPU-Sim ${CMAKE_PROJECT_VERSION} not tested with CUDA version ${CUDAToolkit_VERSION} (please see README)") + endif() +endif() + +# Check for Power model +# TODO How to configure the project to look for it? +message(CHECK_START "Checking for GPGPU-Sim power model") +if(IS_DIRECTORY ${PROJECT_SOURCE_DIR}/src/accelwattch) + if(NOT EXISTS ${PROJECT_SOURCE_DIR}/src/accelwattch/gpgpu_sim.verify) + message(FATAL_ERROR "gpgpu_sim.verify not found in ${PROJECT_SOURCE_DIR}/src/accelwattch/") + endif() + message(CHECK_PASS "${PROJECT_SOURCE_DIR}/src/accelwattch/") + set(GPGPUSIM_USE_POWER_MODEL True) + set(GPGPUSIM_POWER_MODEL ${PROJECT_SOURCE_DIR}/src/accelwattch) +elseif(DEFINED ${GPGPUSIM_POWER_MODEL}) + if(NOT EXISTS ${GPGPUSIM_POWER_MODEL}/gpgpu_sim.verify) + message(FATAL_ERROR "gpgpu_sim.verify not found in ${GPGPUSIM_POWER_MODEL} - Either incorrect directory or incorrect McPAT version") + endif() + message(CHECK_PASS "${GPGPUSIM_POWER_MODEL}") + set(GPGPUSIM_USE_POWER_MODEL True) +else() + message(CHECK_PASS "configured without a power model") +endif() + +# Set Build path +# Get CUDA version +set(CUDA_VERSION_STRING "${CUDAToolkit_VERSION_MAJOR}.${CUDAToolkit_VERSION_MINOR}") +# execute_process( +# COMMAND ${CUDAToolkit_NVCC_EXECUTABLE} --version +# COMMAND awk "/release/ {print $5;}" +# COMMAND sed "s/,//" +# WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} +# OUTPUT_VARIABLE CUDA_VERSION_STRING +# OUTPUT_STRIP_TRAILING_WHITESPACE +# ) + +# CMake cannot do formatted string output, so we just use the good old `awk` +# math(EXPR CUDA_VERSION_NUMBER_MAJOR "${CUDAToolkit_VERSION_MAJOR} * 10") +# math(EXPR CUDA_VERSION_NUMBER_MINOR "${CUDAToolkit_VERSION_MINOR} * 10") +# set(CUDA_VERSION_NUMBER "${CUDA_VERSION_NUMBER_MAJOR}${CUDA_VERSION_NUMBER_MINOR}") +execute_process( + COMMAND echo ${CUDA_VERSION_STRING} + COMMAND sed "s/\\./ /" + COMMAND awk "{printf(\"%02u%02u\", 10*int($1), 10*$2);}" + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + OUTPUT_VARIABLE CUDA_VERSION_NUMBER + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +# Get debug or release +# Set with -DCMAKE_BUILD_TYPE=Debug|Release to change build type +message(CHECK_START "Checking for CMAKE_BUILD_TYPE") +if(NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Release) + set(GPGPUSIM_BUILD_MODE "release" CACHE STRING "" FORCE) +else() + string(TOLOWER "${CMAKE_BUILD_TYPE}" GPGPUSIM_BUILD_MODE) +endif() +message(CHECK_PASS "${CMAKE_BUILD_TYPE}") +# TODO: Make this step an installation phase that handle copying so and creating symlinks +message(STATUS "Setting binary directory to ${CMAKE_BINARY_DIR}") + +# TODO OpenCL check/support? + +list(POP_BACK CMAKE_MESSAGE_INDENT) +message(CHECK_PASS "done") +message(STATUS "Be sure to run 'source setup' " + "before you run CUDA program with GPGPU-Sim or building with external " + "simulator like SST")
\ No newline at end of file diff --git a/gpgpusim_gen_build_string.cmake b/gpgpusim_gen_build_string.cmake new file mode 100644 index 0000000..4559570 --- /dev/null +++ b/gpgpusim_gen_build_string.cmake @@ -0,0 +1,27 @@ +# Get hash +execute_process( + COMMAND git log -1 --format=%h + WORKING_DIRECTORY ${INPUT_DIR} + OUTPUT_VARIABLE GPGPUSIM_GIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE +) + +# Get diff +execute_process( + COMMAND git diff --numstat + COMMAND wc + COMMAND sed -re "s/^\\s+([0-9]+).*/\\1./" + WORKING_DIRECTORY ${INPUT_DIR} + OUTPUT_VARIABLE GPGPUSIM_GIT_DIFF + OUTPUT_STRIP_TRAILING_WHITESPACE +) +execute_process( + COMMAND git diff --numstat --staged + COMMAND wc + COMMAND sed -re "s/^\\s+([0-9]+).*/\\1./" + WORKING_DIRECTORY ${INPUT_DIR} + OUTPUT_VARIABLE GPGPUSIM_GIT_DIFF_STAGED + OUTPUT_STRIP_TRAILING_WHITESPACE +) +set(GPGPUSIM_BUILD_STRING "gpgpu-sim_git-commit-${GPGPUSIM_GIT_HASH}_modified_${GPGPUSIM_GIT_DIFF}${GPGPUSIM_GIT_DIFF_STAGED}") +configure_file(${INPUT_DIR}/version.in ${OUTPUT_DIR}/detailed_version) diff --git a/gpgpusim_gen_setup_environment.cmake b/gpgpusim_gen_setup_environment.cmake new file mode 100644 index 0000000..e74a7f5 --- /dev/null +++ b/gpgpusim_gen_setup_environment.cmake @@ -0,0 +1,31 @@ +# Need to create a setup script to set some variables for others to interact with +set(SETUP_SCRIPT_FILENAME "setup") +message(STATUS "Writing setup commands to '${SETUP_SCRIPT_FILENAME}'") +file(WRITE ${SETUP_SCRIPT_FILENAME} "export GPGPUSIM_SETUP_ENVIRONMENT_WAS_RUN=1\n") +file(APPEND ${SETUP_SCRIPT_FILENAME} "export GPGPUSIM_ROOT=${PROJECT_SOURCE_DIR}\n") +file(APPEND ${SETUP_SCRIPT_FILENAME} "export GPGPUSIM_CONFIG=${GPGPUSIM_CONFIG}\n") +file(APPEND ${SETUP_SCRIPT_FILENAME} "export CUDA_INSTALL_PATH=${CUDAToolkit_TARGET_DIR}\n") +file(APPEND ${SETUP_SCRIPT_FILENAME} "export PATH=`echo $PATH | sed 's#$GPGPUSIM_ROOT/bin:$CUDA_INSTALL_PATH/bin:##'`\n") +file(APPEND ${SETUP_SCRIPT_FILENAME} "export PATH=$GPGPUSIM_ROOT/bin:$CUDA_INSTALL_PATH/bin:$PATH\n") +file(APPEND ${SETUP_SCRIPT_FILENAME} "export CUDA_VERSION_NUMBER=${CUDA_VERSION_NUMBER}\n") +if(CUDA_VERSION_NUMBER GREATER_EQUAL 6000) + file(APPEND ${SETUP_SCRIPT_FILENAME} "export PTX_SIM_USE_PTX_FILE=1.ptx\n") + file(APPEND ${SETUP_SCRIPT_FILENAME} "export PTX_SIM_KERNELFILE=_1.ptx\n") + file(APPEND ${SETUP_SCRIPT_FILENAME} "export CUOBJDUMP_SIM_FILE=jj\n") +endif() +# TODO What about OpenCL support? + +# setting LD_LIBRARY_PATH as follows enables GPGPU-Sim to be invoked by +# native CUDA and OpenCL applications. GPGPU-Sim is dynamically linked +# against instead of the CUDA toolkit. This replaces this cumbersome +# static link setup in prior GPGPU-Sim releases. +# Create a softlink for backward support +if(APPLE) +file(APPEND ${SETUP_SCRIPT_FILENAME} "export DYLD_LIBRARY_PATH=`echo $DYLD_LIBRARY_PATH | sed -Ee 's#'$GPGPUSIM_ROOT'\/lib\/[0-9]+\/(debug|release):##'`\n") +file(APPEND ${SETUP_SCRIPT_FILENAME} "export DYLD_LIBRARY_PATH=$GPGPUSIM_ROOT/lib/$GPGPUSIM_CONFIG:$DYLD_LIBRARY_PATH\n") +else() +file(APPEND ${SETUP_SCRIPT_FILENAME} "export LD_LIBRARY_PATH=`echo $LD_LIBRARY_PATH | sed -re 's#'$GPGPUSIM_ROOT'\/lib\/[0-9]+\/(debug|release):##'`\n") +file(APPEND ${SETUP_SCRIPT_FILENAME} "export LD_LIBRARY_PATH=$GPGPUSIM_ROOT/lib/$GPGPUSIM_CONFIG:$LD_LIBRARY_PATH\n") +endif() + +# TODO ignore the OPENCL_REMOTE_GPU_HOST part?
\ No newline at end of file diff --git a/gpgpusim_install.cmake b/gpgpusim_install.cmake new file mode 100644 index 0000000..1590bf3 --- /dev/null +++ b/gpgpusim_install.cmake @@ -0,0 +1,2 @@ +# TODO Create the build/gcc-X.X/cuda-XXXX/release folder and put so to it +# TODO Also create symlinks to the libcudart.so
\ No newline at end of file diff --git a/gpgpusim_unset_cuda.cmake b/gpgpusim_unset_cuda.cmake new file mode 100644 index 0000000..4eaef91 --- /dev/null +++ b/gpgpusim_unset_cuda.cmake @@ -0,0 +1,60 @@ +# Unset these variable to force a re-search on possible CUDA version changes +unset(CUDAToolkit_BIN_DIR CACHE) +unset(CUDAToolkit_CUPTI_INCLUDE_DIR CACHE) +unset(CUDAToolkit_NVCC_EXECUTABLE CACHE) +unset(CUDAToolkit_rt_LIBRARY CACHE) +unset(CUDA_CUDART CACHE) +unset(CUDA_OpenCL_LIBRARY CACHE) +unset(CUDA_cublasLt_LIBRARY CACHE) +unset(CUDA_cublasLt_static_LIBRARY CACHE) +unset(CUDA_cublas_LIBRARY CACHE) +unset(CUDA_cublas_static_LIBRARY CACHE) +unset(CUDA_cuda_driver_LIBRARY CACHE) +unset(CUDA_cudart_LIBRARY CACHE) +unset(CUDA_cudart_static_LIBRARY CACHE) +unset(CUDA_cufft_LIBRARY CACHE) +unset(CUDA_cufft_static_LIBRARY CACHE) +unset(CUDA_cufft_static_nocallback_LIBRARY CACHE) +unset(CUDA_cufftw_LIBRARY CACHE) +unset(CUDA_cufftw_static_LIBRARY CACHE) +unset(CUDA_culibos_LIBRARY CACHE) +unset(CUDA_cupti_LIBRARY CACHE) +unset(CUDA_cupti_static_LIBRARY CACHE) +unset(CUDA_curand_LIBRARY CACHE) +unset(CUDA_curand_static_LIBRARY CACHE) +unset(CUDA_cusolver_LIBRARY CACHE) +unset(CUDA_cusolver_lapack_static_LIBRARY CACHE) +unset(CUDA_cusolver_static_LIBRARY CACHE) +unset(CUDA_cusparse_LIBRARY CACHE) +unset(CUDA_cusparse_static_LIBRARY CACHE) +unset(CUDA_nppc_LIBRARY CACHE) +unset(CUDA_nppc_static_LIBRARY CACHE) +unset(CUDA_nppial_LIBRARY CACHE) +unset(CUDA_nppial_static_LIBRARY CACHE) +unset(CUDA_nppicc_LIBRARY CACHE) +unset(CUDA_nppicc_static_LIBRARY CACHE) +unset(CUDA_nppicom_LIBRARY CACHE) +unset(CUDA_nppicom_static_LIBRARY CACHE) +unset(CUDA_nppidei_LIBRARY CACHE) +unset(CUDA_nppidei_static_LIBRARY CACHE) +unset(CUDA_nppif_LIBRARY CACHE) +unset(CUDA_nppif_static_LIBRARY CACHE) +unset(CUDA_nppig_LIBRARY CACHE) +unset(CUDA_nppig_static_LIBRARY CACHE) +unset(CUDA_nppim_LIBRARY CACHE) +unset(CUDA_nppim_static_LIBRARY CACHE) +unset(CUDA_nppist_LIBRARY CACHE) +unset(CUDA_nppist_static_LIBRARY CACHE) +unset(CUDA_nppisu_LIBRARY CACHE) +unset(CUDA_nppisu_static_LIBRARY CACHE) +unset(CUDA_nppitc_LIBRARY CACHE) +unset(CUDA_nppitc_static_LIBRARY CACHE) +unset(CUDA_npps_LIBRARY CACHE) +unset(CUDA_npps_static_LIBRARY CACHE) +unset(CUDA_nvToolsExt_LIBRARY CACHE) +unset(CUDA_nvgraph_LIBRARY CACHE) +unset(CUDA_nvgraph_static_LIBRARY CACHE) +unset(CUDA_nvjpeg_LIBRARY CACHE) +unset(CUDA_nvjpeg_static_LIBRARY CACHE) +unset(CUDA_nvml_LIBRARY CACHE) +unset(CUDA_nvrtc_LIBRARY CACHE)
\ No newline at end of file diff --git a/libcuda/CMakeLists.txt b/libcuda/CMakeLists.txt new file mode 100644 index 0000000..c4ba4d1 --- /dev/null +++ b/libcuda/CMakeLists.txt @@ -0,0 +1,26 @@ +# Specify Flex and Bison target +BISON_TARGET(cuobjdump_parser cuobjdump.y ${CMAKE_CURRENT_BINARY_DIR}/cuobjdump_parser.c + COMPILE_FLAGS "-t -d -v --report=all -p cuobjdump_ --file-prefix=${CMAKE_CURRENT_BINARY_DIR}/cuobjdump") +FLEX_TARGET(cuobjdump_lexer cuobjdump.l ${CMAKE_CURRENT_BINARY_DIR}/cuobjdump_lexer.c + COMPILE_FLAGS "-B -P cuobjdump_") +ADD_FLEX_BISON_DEPENDENCY(cuobjdump_lexer cuobjdump_parser) + +# Set generated source files to CXX +set_source_files_properties(${BISON_cuobjdump_parser_OUTPUT_SOURCE} + ${FLEX_cuobjdump_lexer_OUTPUTS} + PROPERTIES LANGUAGE CXX) + +# Create libcuda.a with all source files +add_library(cuda STATIC + cuda_runtime_api.cc + ${BISON_cuobjdump_parser_OUTPUT_SOURCE} ${FLEX_cuobjdump_lexer_OUTPUTS}) + + # Add current dir to include path +# Also add flex/bison generated header files +target_include_directories(cuda PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR}) + +# Add cuda include path for own reference +target_include_directories(cuda PRIVATE ${CUDAToolkit_INCLUDE_DIRS}) + +# Add project build dir to include path +target_include_directories(cuda PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) diff --git a/libcuda/cuda_api_object.h b/libcuda/cuda_api_object.h index d292e22..e620e57 100644 --- a/libcuda/cuda_api_object.h +++ b/libcuda/cuda_api_object.h @@ -1,6 +1,7 @@ #ifndef __cuda_api_object_h__ #define __cuda_api_object_h__ +#include <functional> #include <list> #include <map> #include <set> @@ -193,9 +194,25 @@ class cuda_runtime_api { // backward pointer class gpgpu_context *gpgpu_ctx; // member function list + + // For SST and other potential simulator interface + void cuobjdumpInit(const char *fn); + void extract_code_using_cuobjdump(const char *fn); + void extract_ptx_files_using_cuobjdump(CUctx_st *context, const char *fn); + + // For running GPGPUSim alone void cuobjdumpInit(); void extract_code_using_cuobjdump(); void extract_ptx_files_using_cuobjdump(CUctx_st *context); + + // Internal functions for the above public methods + void cuobjdumpInit_internal(std::function<void()> ctx_extract_code_func); + void extract_code_using_cuobjdump_internal( + CUctx_st *context, std::string &app_binary, + std::function<void(CUctx_st *)> ctx_extract_ptx_func); + void extract_ptx_files_using_cuobjdump_internal(CUctx_st *context, + std::string &app_binary); + std::list<cuobjdumpSection *> pruneSectionList(CUctx_st *context); std::list<cuobjdumpSection *> mergeMatchingSections(std::string identifier); std::list<cuobjdumpSection *> mergeSections(); diff --git a/libcuda/cuda_runtime_api.cc b/libcuda/cuda_runtime_api.cc index fd05f55..5dfd3fc 100644 --- a/libcuda/cuda_runtime_api.cc +++ b/libcuda/cuda_runtime_api.cc @@ -109,6 +109,7 @@ #include <string.h> #include <time.h> #include <fstream> +#include <functional> #include <iostream> #include <regex> #include <sstream> @@ -133,16 +134,16 @@ #if (CUDART_VERSION < 8000) #include "__cudaFatFormat.h" #endif -#include "gpgpu_context.h" -#include "cuda_api_object.h" -#include "../src/gpgpu-sim/gpu-sim.h" -#include "../src/cuda-sim/ptx_loader.h" +#include "../src/abstract_hardware_model.h" #include "../src/cuda-sim/cuda-sim.h" #include "../src/cuda-sim/ptx_ir.h" +#include "../src/cuda-sim/ptx_loader.h" #include "../src/cuda-sim/ptx_parser.h" +#include "../src/gpgpu-sim/gpu-sim.h" #include "../src/gpgpusim_entrypoint.h" #include "../src/stream_manager.h" -#include "../src/abstract_hardware_model.h" +#include "cuda_api_object.h" +#include "gpgpu_context.h" #include <pthread.h> #include <semaphore.h> @@ -151,6 +152,9 @@ #include <mach-o/dyld.h> #endif +// SST cycle +extern bool SST_Cycle(); + /*DEVICE_BUILTIN*/ struct cudaArray { void *devPtr; @@ -412,6 +416,13 @@ void setCuobjdumpsassfilename( //! processes (e.g. cuobjdump) reading /proc/<pid>/exe will see the emulator //! executable instead of the application binary. //! +// In SST need the string to pass the binary information +// as we cannot get it from /proc/self/exe +std::string get_app_binary(const char *fn) { + printf("self exe links to: %s\n", fn); + return fn; +} + std::string get_app_binary() { char self_exe_path[1025]; #ifdef __APPLE__ @@ -435,7 +446,7 @@ std::string get_app_binary() { // above func gives abs path whereas this give just the name of application. char *get_app_binary_name(std::string abs_path) { - char *self_exe_path; + char *self_exe_path = NULL; #ifdef __APPLE__ // TODO: get apple device and check the result. printf("WARNING: not tested for Apple-mac devices \n"); @@ -453,17 +464,27 @@ char *get_app_binary_name(std::string abs_path) { return self_exe_path; } -static int get_app_cuda_version() { +static int get_app_cuda_version_internal(std::string app_binary) { int app_cuda_version = 0; char fname[1024]; snprintf(fname, 1024, "_app_cuda_version_XXXXXX"); int fd = mkstemp(fname); close(fd); + // Weili: Add way to extract CUDA version information from Balar Vanadis + // binary (stored as a const string) std::string app_cuda_version_command = - "ldd " + get_app_binary() + + "ldd " + app_binary + " | grep libcudart.so | sed 's/.*libcudart.so.\\(.*\\) =>.*/\\1/' > " + + fname + " && strings " + app_binary + + " | grep libcudart_vanadis.a | sed " + "'s/.*libcudart_vanadis.a.\\(.*\\)/\\1/' >> " + fname; - system(app_cuda_version_command.c_str()); + int res = system(app_cuda_version_command.c_str()); + if (res == -1) { + printf("Error - Cannot detect the app's CUDA version. Command: %s\n", + app_cuda_version_command.c_str()); + exit(1); + } FILE *cmd = fopen(fname, "r"); char buf[256]; while (fgets(buf, sizeof(buf), cmd) != 0) { @@ -472,12 +493,24 @@ static int get_app_cuda_version() { } fclose(cmd); if (app_cuda_version == 0) { - printf("Error - Cannot detect the app's CUDA version.\n"); + printf("Error - Cannot detect the app's CUDA version. Command: %s\n", + app_cuda_version_command.c_str()); exit(1); } return app_cuda_version; } +static int get_app_cuda_version(const char *fn) { + // Use for other simulator integration + std::string app_binary = get_app_binary(fn); + return get_app_cuda_version_internal(app_binary); +} + +static int get_app_cuda_version() { + std::string app_binary = get_app_binary(); + return get_app_cuda_version_internal(app_binary); +} + //! Keep track of the association between filename and cubin handle void cuda_runtime_api::cuobjdumpRegisterFatBinary(unsigned int handle, const char *filename, @@ -570,8 +603,11 @@ __host__ cudaError_t CUDARTAPI cudaDeviceGetLimitInternal( return g_last_cudaError = cudaSuccess; } -void **cudaRegisterFatBinaryInternal(void *fatCubin, - gpgpu_context *gpgpu_ctx = NULL) { +// Internal implementation for cudaRegisterFatBiaryInternal +void **cudaRegisterFatBiaryInternal_impl( + void *fatCubin, gpgpu_context *gpgpu_ctx, std::string &app_binary_path, + int app_cuda_version, + std::function<void(gpgpu_context *)> ctx_cuobjdumpInit_func) { gpgpu_context *ctx; if (gpgpu_ctx) { ctx = gpgpu_ctx; @@ -602,11 +638,9 @@ void **cudaRegisterFatBinaryInternal(void *fatCubin, // compiled with a newer version of CUDA to run apps compiled with older // versions of CUDA. This is especially useful for PTXPLUS execution. // Skip cuda version check for pytorch application - std::string app_binary_path = get_app_binary(); int pos = app_binary_path.find("python"); if (pos == std::string::npos) { // Not pytorch app : checking cuda version - int app_cuda_version = get_app_cuda_version(); assert( app_cuda_version == CUDART_VERSION / 1000 && "The app must be compiled with same major version as the simulator."); @@ -657,7 +691,7 @@ void **cudaRegisterFatBinaryInternal(void *fatCubin, * then for next calls, only returns the appropriate number */ assert(fat_cubin_handle >= 1); - if (fat_cubin_handle == 1) ctx->api->cuobjdumpInit(); + if (fat_cubin_handle == 1) ctx_cuobjdumpInit_func(ctx); ctx->api->cuobjdumpRegisterFatBinary(fat_cubin_handle, filename, context); return (void **)fat_cubin_handle; @@ -749,6 +783,28 @@ void **cudaRegisterFatBinaryInternal(void *fatCubin, #endif } +void **cudaRegisterFatBinaryInternal(const char *fn, void *fatCubin, + gpgpu_context *gpgpu_ctx = NULL) { + std::string app_binary_path = get_app_binary(fn); + int app_cuda_version = get_app_cuda_version(fn); + auto ctx_cuobjdumpInit = [=](gpgpu_context *ctx) { + ctx->api->cuobjdumpInit(fn); + }; + return cudaRegisterFatBiaryInternal_impl(fatCubin, gpgpu_ctx, app_binary_path, + app_cuda_version, ctx_cuobjdumpInit); +} + +void **cudaRegisterFatBinaryInternal(void *fatCubin, + gpgpu_context *gpgpu_ctx = NULL) { + std::string app_binary_path = get_app_binary(); + int app_cuda_version = get_app_cuda_version(); + auto ctx_cuobjdumpInit = [](gpgpu_context *ctx) { + ctx->api->cuobjdumpInit(); + }; + return cudaRegisterFatBiaryInternal_impl(fatCubin, gpgpu_ctx, app_binary_path, + app_cuda_version, ctx_cuobjdumpInit); +} + void cudaRegisterFunctionInternal(void **fatCubinHandle, const char *hostFun, char *deviceFun, const char *deviceName, int thread_limit, uint3 *tid, uint3 *bid, @@ -1053,6 +1109,24 @@ cudaError_t cudaMallocHostInternal(void **ptr, size_t size, } } +// SST malloc done by vanadis, we just need to record the memory addr +cudaError_t CUDARTAPI cudaMallocHostSSTInternal( + void *addr, size_t size, gpgpu_context *gpgpu_ctx = NULL) { + gpgpu_context *ctx; + if (gpgpu_ctx) { + ctx = gpgpu_ctx; + } else { + ctx = GPGPU_Context(); + } + if (g_debug_execution >= 3) { + announce_call(__my_func__); + } + // track pinned memory size allocated in the host so that same amount of + // memory is also allocated in GPU. + ctx->api->pinned_memory_size[addr] = size; + return g_last_cudaError = cudaSuccess; +} + __host__ cudaError_t CUDARTAPI cudaMallocPitchInternal(void **devPtr, size_t *pitch, size_t width, size_t height, gpgpu_context *gpgpu_ctx = NULL) { @@ -1410,14 +1484,16 @@ cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlagsInternal( function_info *entry = context->get_kernel(hostFunc); printf( "Calculate Maxium Active Block with function ptr=%p, blockSize=%d, " - "SMemSize=%d\n", + "SMemSize=%lu\n", hostFunc, blockSize, dynamicSMemSize); if (flags == cudaOccupancyDefault) { // create kernel_info based on entry dim3 gridDim(context->get_device()->get_gpgpu()->max_cta_per_core() * context->get_device()->get_gpgpu()->get_config().num_shader()); dim3 blockDim(blockSize); - kernel_info_t result(gridDim, blockDim, entry); + // because this fuction is only checking for resource requirements, we do + // not care which stream this kernel runs at, just picked -1 + kernel_info_t result(gridDim, blockDim, entry, -1); // if(entry == NULL){ // *numBlocks = 1; // return g_last_cudaError = cudaErrorUnknown; @@ -2295,13 +2371,77 @@ cudaDeviceSynchronizeInternal(gpgpu_context *gpgpu_ctx = NULL) { * * *******************************************************************************/ -extern "C" { - /******************************************************************************* * * - * * + * SST Specific functions, used by Balar * * * *******************************************************************************/ + +/** + * @brief Custom function to get CUDA function parameter size and offset + * from PTX parsing result + * + * @param hostFun + * @param index + * @return std::tuple<cudaError_t, size_t, unsigned> + */ +std::tuple<cudaError_t, size_t, unsigned> SST_cudaGetParamConfig( + uint64_t hostFun, unsigned index) { + if (g_debug_execution >= 3) { + announce_call(__my_func__); + } + CUctx_st *context = GPGPUSim_Context(GPGPU_Context()); + function_info *entry = context->get_kernel((char *)hostFun); + cudaError_t result = cudaSuccess; + size_t size = 0; + unsigned alignment = 0; + if (index >= entry->num_args()) { + result = cudaErrorAssert; + } else { + std::pair<size_t, unsigned> p = entry->get_param_config(index); + size = p.first; + alignment = p.second; + } + return std::tuple<cudaError_t, size_t, unsigned>(result, size, alignment); +} + +extern "C" { +void SST_receive_mem_reply(unsigned core_id, void *mem_req) { + CUctx_st *context = GPGPUSim_Context(GPGPU_Context()); + static_cast<sst_gpgpu_sim *>(context->get_device()->get_gpgpu()) + ->SST_receive_mem_reply(core_id, mem_req); + // printf("GPGPU-sim: Recived Request\n"); +} + +bool SST_gpu_core_cycle() { return SST_Cycle(); } + +void SST_gpgpusim_numcores_equal_check(unsigned sst_numcores) { + CUctx_st *context = GPGPUSim_Context(GPGPU_Context()); + static_cast<sst_gpgpu_sim *>(context->get_device()->get_gpgpu()) + ->SST_gpgpusim_numcores_equal_check(sst_numcores); +} + +uint64_t cudaMallocSST(void **devPtr, size_t size) { + if (g_debug_execution >= 3) { + announce_call(__my_func__); + } + void *test_malloc; + test_malloc = (void *)malloc(size); + void **test_malloc2 = &test_malloc; + CUctx_st *context = GPGPUSim_Context(GPGPU_Context()); + *test_malloc2 = context->get_device()->get_gpgpu()->gpu_malloc(size); + printf("GPGPU-Sim PTX: cudaMallocing %zu bytes starting at 0x%llx..\n", size, + (unsigned long long)*test_malloc2); + if (g_debug_execution >= 3) + printf("GPGPU-Sim PTX: cudaMallocing %zu bytes starting at 0x%llx..\n", + size, (unsigned long long)*test_malloc2); + return (uint64_t)*test_malloc2; +} + +__host__ cudaError_t CUDARTAPI cudaMallocHostSST(void *addr, size_t size) { + return cudaMallocHostSSTInternal(addr, size); +} + cudaError_t cudaPeekAtLastError(void) { return g_last_cudaError; } __host__ cudaError_t CUDARTAPI cudaMalloc(void **devPtr, size_t size) { @@ -2528,6 +2668,7 @@ cudaError_t CUDARTAPI cudaOccupancyMaxActiveBlocksPerMultiprocessorWithFlags( * * * * *******************************************************************************/ + __host__ cudaError_t CUDARTAPI cudaMemset(void *mem, int c, size_t count) { return cudaMemsetInternal(mem, c, count); } @@ -2748,11 +2889,32 @@ __host__ const char *CUDARTAPI cudaGetErrorString(cudaError_t error) { return strdup(buf); } +// SST specific cuda apis +__host__ cudaError_t CUDARTAPI cudaSetupArgumentSST(uint64_t arg, + uint8_t value[200], + size_t size, + size_t offset) { + void *local_value; + local_value = (void *)malloc(size); + + if (arg) { + memcpy(local_value, (void *)&arg, size); + } else { + memcpy(local_value, value, size); + } + return cudaSetupArgumentInternal(local_value, size, offset); +} + __host__ cudaError_t CUDARTAPI cudaSetupArgument(const void *arg, size_t size, size_t offset) { return cudaSetupArgumentInternal(arg, size, offset); } +// SST specific cuda apis +__host__ cudaError_t CUDARTAPI cudaLaunchSST(uint64_t hostFun) { + return cudaLaunchInternal((char *)hostFun); +} + __host__ cudaError_t CUDARTAPI cudaLaunch(const char *hostFun) { return cudaLaunchInternal(hostFun); } @@ -2927,6 +3089,27 @@ __host__ cudaError_t CUDARTAPI cudaThreadSynchronize(void) { return cudaThreadSynchronizeInternal(); } +__host__ cudaError_t CUDARTAPI cudaThreadSynchronizeSST(void) { + // For SST, perform a one-time check and let SST_Cycle() + // do the polling test and invoke callback to SST + // to signal ThreadSynchonize done + gpgpu_context *ctx = GPGPU_Context(); + if (g_debug_execution >= 3) { + announce_call(__my_func__); + } + + // Called on host side + bool thread_sync_done = ctx->synchronize_check(); + g_last_cudaError = cudaSuccess; + if (thread_sync_done) { + // We are already done, so no need to poll for sync done + ctx->requested_synchronize = false; + return cudaSuccess; + } else { + return cudaErrorNotReady; + } +} + int CUDARTAPI __cudaSynchronizeThreads(void **, void *) { if (g_debug_execution >= 3) { announce_call(__my_func__); @@ -2986,10 +3169,10 @@ __host__ cudaError_t CUDARTAPI cudaGetExportTable( // extracts all ptx files from binary and dumps into // prog_name.unique_no.sm_<>.ptx files -void cuda_runtime_api::extract_ptx_files_using_cuobjdump(CUctx_st *context) { +void cuda_runtime_api::extract_ptx_files_using_cuobjdump_internal( + CUctx_st *context, std::string &app_binary) { char command[1000]; char *pytorch_bin = getenv("PYTORCH_BIN"); - std::string app_binary = get_app_binary(); char ptx_list_file_name[1024]; snprintf(ptx_list_file_name, 1024, "_cuobjdump_list_ptx_XXXXXX"); @@ -3056,6 +3239,17 @@ void cuda_runtime_api::extract_ptx_files_using_cuobjdump(CUctx_st *context) { } } +void cuda_runtime_api::extract_ptx_files_using_cuobjdump(CUctx_st *context, + const char *fn) { + std::string app_binary = get_app_binary(fn); + this->extract_ptx_files_using_cuobjdump_internal(context, app_binary); +} + +void cuda_runtime_api::extract_ptx_files_using_cuobjdump(CUctx_st *context) { + std::string app_binary = get_app_binary(); + this->extract_ptx_files_using_cuobjdump_internal(context, app_binary); +} + //! Call cuobjdump to extract everything (-elf -sass -ptx) /*! * This Function extract the whole PTX (for all the files) using cuobjdump @@ -3063,13 +3257,12 @@ void cuda_runtime_api::extract_ptx_files_using_cuobjdump(CUctx_st *context) { *with each binary in its own file It is also responsible for extracting the *libraries linked to the binary if the option is enabled * */ -void cuda_runtime_api::extract_code_using_cuobjdump() { - CUctx_st *context = GPGPUSim_Context(gpgpu_ctx); - +void cuda_runtime_api::extract_code_using_cuobjdump_internal( + CUctx_st *context, std::string &app_binary, + std::function<void(CUctx_st *)> ctx_extract_ptx_func) { // prevent the dumping by cuobjdump everytime we execute the code! const char *override_cuobjdump = getenv("CUOBJDUMP_SIM_FILE"); char command[1000]; - std::string app_binary = get_app_binary(); // Running cuobjdump using dynamic link to current process snprintf(command, 1000, "md5sum %s ", app_binary.c_str()); printf("Running md5sum using \"%s\"\n", command); @@ -3084,7 +3277,7 @@ void cuda_runtime_api::extract_code_using_cuobjdump() { // used by ptxas. int result = 0; #if (CUDART_VERSION >= 6000) - extract_ptx_files_using_cuobjdump(context); + ctx_extract_ptx_func(context); return; #endif // TODO: redundant to dump twice. how can it be prevented? @@ -3216,6 +3409,26 @@ void cuda_runtime_api::extract_code_using_cuobjdump() { } } +void cuda_runtime_api::extract_code_using_cuobjdump(const char *fn) { + CUctx_st *context = GPGPUSim_Context(gpgpu_ctx); + std::string app_binary = get_app_binary(fn); + auto ctx_extract_ptx_func = [=](CUctx_st *context) { + extract_ptx_files_using_cuobjdump(context, fn); + }; + extract_code_using_cuobjdump_internal(context, app_binary, + ctx_extract_ptx_func); +} + +void cuda_runtime_api::extract_code_using_cuobjdump() { + CUctx_st *context = GPGPUSim_Context(gpgpu_ctx); + std::string app_binary = get_app_binary(); + auto ctx_extract_ptx_func = [=](CUctx_st *context) { + extract_ptx_files_using_cuobjdump(context); + }; + extract_code_using_cuobjdump_internal(context, app_binary, + ctx_extract_ptx_func); +} + //! Read file into char* // TODO: convert this to C++ streams, will be way cleaner char *readfile(const std::string filename) { @@ -3234,7 +3447,12 @@ char *readfile(const std::string filename) { fseek(fp, 0, SEEK_SET); // allocate and copy the entire ptx char *ret = (char *)malloc((filesize + 1) * sizeof(char)); - fread(ret, 1, filesize, fp); + int num = fread(ret, 1, filesize, fp); + if (num == 0) { + std::cout << "ERROR: Could not read data from file %s\n" + << filename << std::endl; + assert(0); + } ret[filesize] = '\0'; fclose(fp); return ret; @@ -3455,10 +3673,11 @@ cuobjdumpPTXSection *cuda_runtime_api::findPTXSection( } //! Extract the code using cuobjdump and remove unnecessary sections -void cuda_runtime_api::cuobjdumpInit() { +void cuda_runtime_api::cuobjdumpInit_internal( + std::function<void()> ctx_extract_code_func) { CUctx_st *context = GPGPUSim_Context(gpgpu_ctx); - extract_code_using_cuobjdump(); // extract all the output of cuobjdump to - // _cuobjdump_*.* + ctx_extract_code_func(); // extract all the output of cuobjdump to + // _cuobjdump_*.* const char *pre_load = getenv("CUOBJDUMP_SIM_FILE"); if (pre_load == NULL || strlen(pre_load) == 0) { cuobjdumpSectionList = pruneSectionList(context); @@ -3466,6 +3685,16 @@ void cuda_runtime_api::cuobjdumpInit() { } } +void cuda_runtime_api::cuobjdumpInit(const char *fn) { + auto ctx_extract_code_func = [=]() { extract_code_using_cuobjdump(fn); }; + cuobjdumpInit_internal(ctx_extract_code_func); +} + +void cuda_runtime_api::cuobjdumpInit() { + auto ctx_extract_code_func = [=]() { extract_code_using_cuobjdump(); }; + cuobjdumpInit_internal(ctx_extract_code_func); +} + //! Either submit PTX for simulation or convert SASS to PTXPlus and submit it void gpgpu_context::cuobjdumpParseBinary(unsigned int handle) { CUctx_st *context = GPGPUSim_Context(this); @@ -3478,7 +3707,7 @@ void gpgpu_context::cuobjdumpParseBinary(unsigned int handle) { context->add_binary(symtab, handle); return; } - symbol_table *symtab; + symbol_table *symtab = NULL; #if (CUDART_VERSION >= 6000) // loops through all ptx files from smallest sm version to largest @@ -3576,6 +3805,10 @@ void gpgpu_context::cuobjdumpParseBinary(unsigned int handle) { extern "C" { +void **CUDARTAPI __cudaRegisterFatBinarySST(const char *fn) { + return cudaRegisterFatBinaryInternal(fn, NULL); +} + void **CUDARTAPI __cudaRegisterFatBinary(void *fatCubin) { if (g_debug_execution >= 3) { announce_call(__my_func__); @@ -3596,6 +3829,7 @@ unsigned CUDARTAPI __cudaPushCallConfiguration(dim3 gridDim, dim3 blockDim, announce_call(__my_func__); } cudaConfigureCallInternal(gridDim, blockDim, sharedMem, stream); + return 0; } cudaError_t CUDARTAPI __cudaPopCallConfiguration(dim3 *gridDim, dim3 *blockDim, @@ -3607,6 +3841,14 @@ cudaError_t CUDARTAPI __cudaPopCallConfiguration(dim3 *gridDim, dim3 *blockDim, return g_last_cudaError = cudaSuccess; } +void CUDARTAPI __cudaRegisterFunctionSST(unsigned fatCubinHandle, + uint64_t hostFun, + char deviceFun[512]) { + cudaRegisterFunctionInternal((void **)fatCubinHandle, (const char *)hostFun, + (char *)deviceFun, NULL, NULL, NULL, NULL, NULL, + NULL); +} + void CUDARTAPI __cudaRegisterFunction(void **fatCubinHandle, const char *hostFun, char *deviceFun, const char *deviceName, int thread_limit, diff --git a/libcuda/gpgpu_context.h b/libcuda/gpgpu_context.h index d0cd7c4..5ef2117 100644 --- a/libcuda/gpgpu_context.h +++ b/libcuda/gpgpu_context.h @@ -44,6 +44,9 @@ class gpgpu_context { s_g_pc_to_insn; // a direct mapping from PC to instruction bool debug_tensorcore; + // SST related + bool requested_synchronize = false; + // objects pointers for each file cuda_runtime_api *api; ptxinfo_data *ptxinfo; @@ -54,6 +57,7 @@ class gpgpu_context { ptx_stats *stats; // member function list void synchronize(); + bool synchronize_check(); void exit_simulation(); void print_simulation_time(); int gpgpu_opencl_ptx_sim_main_perf(kernel_info_t *grid); diff --git a/libopencl/CMakeLists.txt b/libopencl/CMakeLists.txt new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/libopencl/CMakeLists.txt diff --git a/setup_environment b/setup_environment index d3ff840..2fac1b9 100644 --- a/setup_environment +++ b/setup_environment @@ -7,7 +7,7 @@ export GPGPUSIM_ROOT="$( cd "$( dirname "$BASH_SOURCE" )" && pwd )" GPGPUSIM_VERSION_STRING=`cat $GPGPUSIM_ROOT/version | awk '/Version/ {print $8}'` #Detect Git branch and commit # -GIT_COMMIT=`git --git-dir=$GPGPUSIM_ROOT/.git log -n 1 | head -1 | sed -re 's/commit (.*)/\1/'` +GIT_COMMIT=`git --git-dir=$GPGPUSIM_ROOT/.git log --abbrev-commit -n 1 | head -1 | sed -re 's/commit (.*)/\1/'` GIT_FILES_CHANGED=`git --git-dir=$GPGPUSIM_ROOT/.git diff --numstat | wc | sed -re 's/^\s+([0-9]+).*/\1./'` GIT_FILES_CHANGED+=`git --git-dir=$GPGPUSIM_ROOT/.git diff --numstat --cached | wc | sed -re 's/^\s+([0-9]+).*/\1/'` GPGPUSIM_BUILD_STRING="gpgpu-sim_git-commit-$GIT_COMMIT-modified_$GIT_FILES_CHANGED" @@ -16,17 +16,17 @@ echo -n "GPGPU-Sim version $GPGPUSIM_VERSION_STRING (build $GPGPUSIM_BUILD_STRIN if [ ! -n "$CUDA_INSTALL_PATH" ]; then echo "ERROR ** Install CUDA Toolkit and set CUDA_INSTALL_PATH."; - return; + return 1; fi if [ ! -d "$CUDA_INSTALL_PATH" ]; then echo "ERROR ** CUDA_INSTALL_PATH=$CUDA_INSTALL_PATH invalid (directory does not exist)"; - return; + return 1; fi if [ ! `uname` = "Linux" -a ! `uname` = "Darwin" ]; then echo "ERROR ** Unsupported platform: GPGPU-Sim $GPGPUSIM_VERSION_STRING developed and tested on Linux." - return; + return 1; fi export PATH=`echo $PATH | sed "s#$GPGPUSIM_ROOT/bin:$CUDA_INSTALL_PATH/bin:##"` @@ -41,17 +41,17 @@ if [ $? = 1 ]; then echo " Try adding $CUDA_INSTALL_PATH/bin/ to your PATH environment variable."; echo " Please also be sure to read the README file if you have not done so."; echo ""; - return; + return 1; fi -CC_VERSION=`gcc --version | head -1 | awk '{for(i=1;i<=NF;i++){ if(match($i,/^[0-9]\.[0-9]\.[0-9]$/)) {print $i; exit 0}}}'` +CC_VERSION=$(gcc --version | head -1 | awk '{for(i=1;i<=NF;i++){ if(match($i,/^[0-9]+\.[0-9]+\.[0-9]+$/)) {print $i; exit 0}}}') CUDA_VERSION_STRING=`$CUDA_INSTALL_PATH/bin/nvcc --version | awk '/release/ {print $5;}' | sed 's/,//'`; export CUDA_VERSION_NUMBER=`echo $CUDA_VERSION_STRING | sed 's/\./ /' | awk '{printf("%02u%02u", 10*int($1), 10*$2);}'` if [ $CUDA_VERSION_NUMBER -gt 11100 -o $CUDA_VERSION_NUMBER -lt 2030 ]; then echo "ERROR ** GPGPU-Sim version $GPGPUSIM_VERSION_STRING not tested with CUDA version $CUDA_VERSION_STRING (please see README)"; echo $CUDA_VERSION_NUMBER - return + return 1; fi if [ $CUDA_VERSION_NUMBER -ge 6000 ]; then @@ -60,13 +60,18 @@ if [ $CUDA_VERSION_NUMBER -ge 6000 ]; then export CUOBJDUMP_SIM_FILE=jj fi +# Simple configure, loop through all positional arguments +# Default config +export GPGPUSIM_CONFIG=gcc-$CC_VERSION/cuda-$CUDA_VERSION_NUMBER/release -if [ $# = '1' ] ; -then - export GPGPUSIM_CONFIG=gcc-$CC_VERSION/cuda-$CUDA_VERSION_NUMBER/$1 -else - export GPGPUSIM_CONFIG=gcc-$CC_VERSION/cuda-$CUDA_VERSION_NUMBER/release -fi +for opt in $@ +do + if [[ $opt == 'debug' ]] ; then + # Debug mode + echo -n "enabled debug mode " + export GPGPUSIM_CONFIG=gcc-$CC_VERSION/cuda-$CUDA_VERSION_NUMBER/$1 + fi +done export QTINC=/usr/include @@ -121,7 +126,7 @@ fi if [ -d $GPGPUSIM_ROOT/src/accelwattch/ ]; then if [ ! -f $GPGPUSIM_ROOT/src/accelwattch/gpgpu_sim.verify ]; then echo "ERROR ** gpgpu_sim.verify not found in $GPGPUSIM_ROOT/src/accelwattch"; - return; + return 1; fi export GPGPUSIM_POWER_MODEL=$GPGPUSIM_ROOT/src/accelwattch/; echo "configured with AccelWattch."; @@ -129,13 +134,13 @@ elif [ -n "$GPGPUSIM_POWER_MODEL" ]; then if [ ! -f $GPGPUSIM_POWER_MODEL/gpgpu_sim.verify ]; then echo ""; echo "ERROR ** gpgpu_sim.verify not found in $GPGPUSIM_ROOT/src/accelwattch/ - Either incorrect directory or incorrect McPAT version"; - return; + return 1; fi echo "configure with power model in $GPGPUSIM_POWER_MODEL."; elif [ ! -d $GPGPUSIM_POWER_MODEL ]; then echo ""; echo "ERROR ** GPGPUSIM_POWER_MODEL ($GPGPUSIM_POWER_MODEL) does not exist... Please set this to the gpgpusim_mcpat directory or unset this environment variable."; - return; + return 1; else echo "configured without a power model."; fi @@ -143,21 +148,26 @@ fi if [ -z "$PTXAS_CUDA_INSTALL_PATH" ]; then export PTXAS_CUDA_INSTALL_PATH=$CUDA_INSTALL_PATH; fi -echo ""; -echo "----------------------------------------------------------------------------"; -echo "INFO - If you only care about PTX execution, ignore this message. GPGPU-Sim supports PTX execution in modern CUDA." -echo "If you want to run PTXPLUS (sm_1x SASS) with a modern card configuration - set the envronment variable" -echo "\$PTXAS_CUDA_INSTALL_PATH to point a CUDA version compabible with your card configurations (i.e. 8+ for PASCAL, 9+ for VOLTA etc..)" -echo "For example: \"export \$PTXAS_CUDA_INSTALL_PATH=/usr/local/cuda-9.1\"" -echo "" -echo "The following text describes why:"; -echo "If you are using PTXPLUS, only sm_1x is supported and it requires that the app and simulator binaries are compiled in CUDA 4.2 or less."; -echo "The simulator requires it since CUDA headers desribe struct sizes in the exec which change from gen to gen."; -echo "The apps require 4.2 because new versions of CUDA tools have dropped parsing support for generating sm_1x"; -echo "When running using modern config (i.e. volta) and PTXPLUS with CUDA 4.2, the \$PTXAS_CUDA_INSTALL_PATH env variable is required to get proper register usage" -echo "(and hence occupancy) using a version of CUDA that knows the register usage on the real card." -echo ""; -echo "----------------------------------------------------------------------------"; + +# I am not sure PTXPlus really makes sense anymore and this verbose print to describe +# how to use it is probably not aging well. The info in here is good though if you care +# about PTXPlus, so I will leave it as a comment. +# +#echo ""; +#echo "----------------------------------------------------------------------------"; +#echo "INFO - If you only care about PTX execution or trace-based SASS execution, ignore this message." +#echo "If you want to run PTXPLUS (sm_1x SASS) with a modern card configuration - set the envronment variable" +#echo "\$PTXAS_CUDA_INSTALL_PATH to point a CUDA version compabible with your card configurations (i.e. 8+ for PASCAL, 9+ for VOLTA etc..)" +#echo "For example: \"export \$PTXAS_CUDA_INSTALL_PATH=/usr/local/cuda-9.1\"" +#echo "" +#echo "The following text describes why:"; +#echo "If you are using PTXPLUS, only sm_1x is supported and it requires that the app and simulator binaries are compiled in CUDA 4.2 or less."; +#echo "The simulator requires it since CUDA headers desribe struct sizes in the exec which change from gen to gen."; +#echo "The apps require 4.2 because new versions of CUDA tools have dropped parsing support for generating sm_1x"; +#echo "When running using modern config (i.e. volta) and PTXPLUS with CUDA 4.2, the \$PTXAS_CUDA_INSTALL_PATH env variable is required to get proper register usage" +#echo "(and hence occupancy) using a version of CUDA that knows the register usage on the real card." +#echo ""; +#echo "----------------------------------------------------------------------------"; echo "setup_environment succeeded"; diff --git a/short-tests-accelsim.sh b/short-tests-accelsim.sh new file mode 100755 index 0000000..5cb4d2c --- /dev/null +++ b/short-tests-accelsim.sh @@ -0,0 +1,39 @@ +if [ ! -n "$CUDA_INSTALL_PATH" ]; then + echo "ERROR ** Install CUDA Toolkit and set CUDA_INSTALL_PATH."; + exit 1; +fi + +if [ ! -n "$ACCELSIM_BRANCH" ]; then + echo "ERROR ** set the ACCELSIM_BRANCH env variable"; + exit 1; +fi + +if [ ! -n "$GPUAPPS_ROOT" ]; then + echo "ERROR ** GPUAPPS_ROOT to a location where the apps have been compiled"; + exit 1; +fi + +git config --system --add safe.directory '*' + +export PATH=$CUDA_INSTALL_PATH/bin:$PATH +source ./setup_environment +make -j + +git clone https://github.com/accel-sim/accel-sim-framework.git + +# Build accel-sim +cd accel-sim-framework +git checkout $ACCELSIM_BRANCH +source ./gpu-simulator/setup_environment.sh +make -j -C ./gpu-simulator + +# Get rodinia traces +rm -rf ./hw_run/rodinia_2.0-ft +wget https://engineering.purdue.edu/tgrogers/accel-sim/traces/tesla-v100/latest/rodinia_2.0-ft.tgz +mkdir -p ./hw_run +tar -xzvf rodinia_2.0-ft.tgz -C ./hw_run +rm rodinia_2.0-ft.tgz + +# Run rodinia traces +./util/job_launching/run_simulations.py -C QV100-SASS -B rodinia_2.0-ft -T ./hw_run/rodinia_2.0-ft/9.1 -N myTest +./util/job_launching/monitor_func_test.py -v -N myTest diff --git a/short-tests-cmake.sh b/short-tests-cmake.sh new file mode 100755 index 0000000..23cf66c --- /dev/null +++ b/short-tests-cmake.sh @@ -0,0 +1,27 @@ +if [ ! -n "$CUDA_INSTALL_PATH" ]; then + echo "ERROR ** Install CUDA Toolkit and set CUDA_INSTALL_PATH."; + exit 1; +fi + +if [ ! -n "$CONFIG" ]; then + echo "ERROR ** set the CONFIG env variable to one of those found in ./accel-sim-framework/util/job_launching/configs/define-standard-cfgs.yml"; + exit 1; +fi + +if [ ! -n "$GPUAPPS_ROOT" ]; then + echo "ERROR ** GPUAPPS_ROOT to a location where the apps have been compiled"; + exit 1; +fi + +git config --system --add safe.directory '*' + +export PATH=$CUDA_INSTALL_PATH/bin:$PATH + +cmake -B build +cmake --build build -j +cmake --install build +source setup + +git clone https://github.com/accel-sim/accel-sim-framework.git +./accel-sim-framework/util/job_launching/run_simulations.py -C $CONFIG -B rodinia_2.0-ft -N regress -l local +./accel-sim-framework/util/job_launching/monitor_func_test.py -v -N regress -j procman diff --git a/travis.sh b/short-tests.sh index bbdd19a..a1db762 100755 --- a/travis.sh +++ b/short-tests.sh @@ -1,24 +1,24 @@ if [ ! -n "$CUDA_INSTALL_PATH" ]; then echo "ERROR ** Install CUDA Toolkit and set CUDA_INSTALL_PATH."; - exit; + exit 1; fi if [ ! -n "$CONFIG" ]; then echo "ERROR ** set the CONFIG env variable to one of those found in ./accel-sim-framework/util/job_launching/configs/define-standard-cfgs.yml"; - exit; + exit 1; fi if [ ! -n "$GPUAPPS_ROOT" ]; then echo "ERROR ** GPUAPPS_ROOT to a location where the apps have been compiled"; - exit; + exit 1; fi +git config --system --add safe.directory '*' + export PATH=$CUDA_INSTALL_PATH/bin:$PATH source ./setup_environment make -j -pip install psutil -rm -rf accel-sim-framework git clone https://github.com/accel-sim/accel-sim-framework.git ./accel-sim-framework/util/job_launching/run_simulations.py -C $CONFIG -B rodinia_2.0-ft -N regress -l local ./accel-sim-framework/util/job_launching/monitor_func_test.py -v -N regress -j procman diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..5849629 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,19 @@ +# gpgpusim_entrypoint objects +add_library(gpgpusim_entrypoint OBJECT + abstract_hardware_model.cc + debug.cc + gpgpusim_entrypoint.cc + option_parser.cc + statwrapper.cc + stream_manager.cc + trace.cc) + +# Add current folder and CUDA include to include path +target_include_directories(gpgpusim_entrypoint PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(gpgpusim_entrypoint PUBLIC ${CUDAToolkit_INCLUDE_DIRS}) + +# Add subdir +add_subdirectory(accelwattch) +add_subdirectory(cuda-sim) +add_subdirectory(gpgpu-sim) +add_subdirectory(intersim2)
\ No newline at end of file diff --git a/src/abstract_hardware_model.cc b/src/abstract_hardware_model.cc index 208047e..e8ddf95 100644 --- a/src/abstract_hardware_model.cc +++ b/src/abstract_hardware_model.cc @@ -1,16 +1,18 @@ -// Copyright (c) 2009-2021, Tor M. Aamodt, Inderpreet Singh, Timothy Rogers, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// Copyright (c) 2009-2021, Tor M. Aamodt, Inderpreet Singh, Timothy Rogers, +// Vijay Kandiah, Nikos Hardavellas, Mahmoud Khairy, Junrui Pan, Timothy G. +// Rogers The University of British Columbia, Northwestern University, Purdue +// University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -27,7 +29,6 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. - #include "abstract_hardware_model.h" #include <sys/stat.h> #include <algorithm> @@ -48,12 +49,14 @@ void mem_access_t::init(gpgpu_context *ctx) { m_addr = 0; m_req_size = 0; } + void warp_inst_t::issue(const active_mask_t &mask, unsigned warp_id, unsigned long long cycle, int dynamic_warp_id, - int sch_id) { + int sch_id, unsigned long long streamID) { m_warp_active_mask = mask; m_warp_issued_mask = mask; m_uid = ++(m_config->gpgpu_ctx->warp_inst_sm_next_uid); + m_streamID = streamID; m_warp_id = warp_id; m_dynamic_warp_id = dynamic_warp_id; issue_cycle = cycle; @@ -74,7 +77,7 @@ void checkpoint::load_global_mem(class memory_space *temp_mem, char *f1name) { FILE *fp2 = fopen(f1name, "r"); assert(fp2 != NULL); char line[128]; /* or other suitable maximum line size */ - unsigned int offset; + unsigned int offset = 0; while (fgets(line, sizeof line, fp2) != NULL) /* read a line */ { unsigned int index; @@ -283,7 +286,7 @@ void warp_inst_t::broadcast_barrier_reduction( void warp_inst_t::generate_mem_accesses() { if (empty() || op == MEMORY_BARRIER_OP || m_mem_accesses_created) return; if (!((op == LOAD_OP) || (op == TENSOR_CORE_LOAD_OP) || (op == STORE_OP) || - (op == TENSOR_CORE_STORE_OP) )) + (op == TENSOR_CORE_STORE_OP))) return; if (m_warp_active_mask.count() == 0) return; // predicated off @@ -291,8 +294,8 @@ void warp_inst_t::generate_mem_accesses() { assert(is_load() || is_store()); - //if((space.get_type() != tex_space) && (space.get_type() != const_space)) - assert(m_per_scalar_thread_valid); // need address information per thread + // if((space.get_type() != tex_space) && (space.get_type() != const_space)) + assert(m_per_scalar_thread_valid); // need address information per thread bool is_write = is_store(); @@ -754,7 +757,8 @@ void warp_inst_t::completed(unsigned long long cycle) const { } kernel_info_t::kernel_info_t(dim3 gridDim, dim3 blockDim, - class function_info *entry) { + class function_info *entry, + unsigned long long streamID) { m_kernel_entry = entry; m_grid_dim = gridDim; m_block_dim = blockDim; @@ -764,6 +768,7 @@ kernel_info_t::kernel_info_t(dim3 gridDim, dim3 blockDim, m_next_tid = m_next_cta; m_num_cores_running = 0; m_uid = (entry->gpgpu_ctx->kernel_info_m_next_uid)++; + m_streamID = streamID; m_param_mem = new memory_space_impl<8192>("param", 64 * 1024); // Jin: parent and child kernel management for CDP @@ -1005,13 +1010,13 @@ void simt_stack::print(FILE *fout) const { } for (unsigned j = 0; j < m_warp_size; j++) fprintf(fout, "%c", (stack_entry.m_active_mask.test(j) ? '1' : '0')); - fprintf(fout, " pc: 0x%03x", stack_entry.m_pc); + fprintf(fout, " pc: 0x%03llx", stack_entry.m_pc); if (stack_entry.m_recvg_pc == (unsigned)-1) { fprintf(fout, " rp: ---- tp: %s cd: %2u ", (stack_entry.m_type == STACK_ENTRY_TYPE_CALL ? "C" : "N"), stack_entry.m_calldepth); } else { - fprintf(fout, " rp: %4u tp: %s cd: %2u ", stack_entry.m_recvg_pc, + fprintf(fout, " rp: %4llu tp: %s cd: %2u ", stack_entry.m_recvg_pc, (stack_entry.m_type == STACK_ENTRY_TYPE_CALL ? "C" : "N"), stack_entry.m_calldepth); } @@ -1031,7 +1036,7 @@ void simt_stack::print_checkpoint(FILE *fout) const { for (unsigned j = 0; j < m_warp_size; j++) fprintf(fout, "%c ", (stack_entry.m_active_mask.test(j) ? '1' : '0')); - fprintf(fout, "%d %d %d %lld %d ", stack_entry.m_pc, + fprintf(fout, "%llu %d %llu %lld %d ", stack_entry.m_pc, stack_entry.m_calldepth, stack_entry.m_recvg_pc, stack_entry.m_branch_div_cycle, stack_entry.m_type); fprintf(fout, "%d %d\n", m_warp_id, m_warp_size); diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h index f04741f..98a4039 100644 --- a/src/abstract_hardware_model.h +++ b/src/abstract_hardware_model.h @@ -1,16 +1,18 @@ -// Copyright (c) 2009-2021, Tor M. Aamodt, Inderpreet Singh, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University +// Copyright (c) 2009-2021, Tor M. Aamodt, Inderpreet Singh, Vijay Kandiah, +// Nikos Hardavellas, Mahmoud Khairy, Junrui Pan, Timothy G. Rogers The +// University of British Columbia, Northwestern University, Purdue University // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -63,24 +65,24 @@ enum _memory_space_t { #ifndef COEFF_STRUCT #define COEFF_STRUCT -struct PowerscalingCoefficients{ - double int_coeff; - double int_mul_coeff; - double int_mul24_coeff; - double int_mul32_coeff; - double int_div_coeff; - double fp_coeff; - double dp_coeff; - double fp_mul_coeff; - double fp_div_coeff; - double dp_mul_coeff; - double dp_div_coeff; - double sqrt_coeff; - double log_coeff; - double sin_coeff; - double exp_coeff; - double tensor_coeff; - double tex_coeff; +struct PowerscalingCoefficients { + double int_coeff; + double int_mul_coeff; + double int_mul24_coeff; + double int_mul32_coeff; + double int_div_coeff; + double fp_coeff; + double dp_coeff; + double fp_mul_coeff; + double fp_div_coeff; + double dp_mul_coeff; + double dp_div_coeff; + double sqrt_coeff; + double log_coeff; + double sin_coeff; + double exp_coeff; + double tensor_coeff; + double tex_coeff; }; #endif @@ -231,7 +233,8 @@ class kernel_info_t { // m_num_cores_running=0; // m_param_mem=NULL; // } - kernel_info_t(dim3 gridDim, dim3 blockDim, class function_info *entry); + kernel_info_t(dim3 gridDim, dim3 blockDim, class function_info *entry, + unsigned long long streamID); kernel_info_t( dim3 gridDim, dim3 blockDim, class function_info *entry, std::map<std::string, const struct cudaArray *> nameToCudaArray, @@ -290,6 +293,8 @@ class kernel_info_t { m_next_tid.x < m_block_dim.x; } unsigned get_uid() const { return m_uid; } + unsigned long long get_streamID() const { return m_streamID; } + std::string get_name() const { return name(); } std::string name() const; std::list<class ptx_thread_info *> &active_threads() { @@ -322,7 +327,8 @@ class kernel_info_t { class function_info *m_kernel_entry; - unsigned m_uid; + unsigned m_uid; // Kernel ID + unsigned long long m_streamID; // These maps contain the snapshot of the texture mappings at kernel launch std::map<std::string, const struct cudaArray *> m_NameToCudaArray; @@ -897,8 +903,8 @@ class mem_fetch_interface { class mem_fetch_allocator { public: virtual mem_fetch *alloc(new_addr_type addr, mem_access_type type, - unsigned size, bool wr, - unsigned long long cycle) const = 0; + unsigned size, bool wr, unsigned long long cycle, + unsigned long long streamID) const = 0; virtual mem_fetch *alloc(const class warp_inst_t &inst, const mem_access_t &access, unsigned long long cycle) const = 0; @@ -908,7 +914,8 @@ class mem_fetch_allocator { const mem_access_sector_mask_t §or_mask, unsigned size, bool wr, unsigned long long cycle, unsigned wid, unsigned sid, unsigned tpc, - mem_fetch *original_mf) const = 0; + mem_fetch *original_mf, + unsigned long long streamID) const = 0; }; // the maximum number of destination, source, or address uarch operands in a @@ -961,7 +968,7 @@ class inst_t { } bool valid() const { return m_decoded; } virtual void print_insn(FILE *fp) const { - fprintf(fp, " [inst @ pc=0x%04x] ", pc); + fprintf(fp, " [inst @ pc=0x%04llx] ", pc); } bool is_load() const { return (op == LOAD_OP || op == TENSOR_CORE_LOAD_OP || @@ -972,18 +979,22 @@ class inst_t { memory_op == memory_store); } - bool is_fp() const { return ((sp_op == FP__OP));} //VIJAY - bool is_fpdiv() const { return ((sp_op == FP_DIV_OP));} - bool is_fpmul() const { return ((sp_op == FP_MUL_OP));} - bool is_dp() const { return ((sp_op == DP___OP));} - bool is_dpdiv() const { return ((sp_op == DP_DIV_OP));} - bool is_dpmul() const { return ((sp_op == DP_MUL_OP));} - bool is_imul() const { return ((sp_op == INT_MUL_OP));} - bool is_imul24() const { return ((sp_op == INT_MUL24_OP));} - bool is_imul32() const { return ((sp_op == INT_MUL32_OP));} - bool is_idiv() const { return ((sp_op == INT_DIV_OP));} - bool is_sfu() const {return ((sp_op == FP_SQRT_OP) || (sp_op == FP_LG_OP) || (sp_op == FP_SIN_OP) || (sp_op == FP_EXP_OP) || (sp_op == TENSOR__OP));} - bool is_alu() const {return (sp_op == INT__OP);} + bool is_fp() const { return ((sp_op == FP__OP)); } // VIJAY + bool is_fpdiv() const { return ((sp_op == FP_DIV_OP)); } + bool is_fpmul() const { return ((sp_op == FP_MUL_OP)); } + bool is_dp() const { return ((sp_op == DP___OP)); } + bool is_dpdiv() const { return ((sp_op == DP_DIV_OP)); } + bool is_dpmul() const { return ((sp_op == DP_MUL_OP)); } + bool is_imul() const { return ((sp_op == INT_MUL_OP)); } + bool is_imul24() const { return ((sp_op == INT_MUL24_OP)); } + bool is_imul32() const { return ((sp_op == INT_MUL32_OP)); } + bool is_idiv() const { return ((sp_op == INT_DIV_OP)); } + bool is_sfu() const { + return ((sp_op == FP_SQRT_OP) || (sp_op == FP_LG_OP) || + (sp_op == FP_SIN_OP) || (sp_op == FP_EXP_OP) || + (sp_op == TENSOR__OP)); + } + bool is_alu() const { return (sp_op == INT__OP); } unsigned get_num_operands() const { return num_operands; } unsigned get_num_regs() const { return num_regs; } @@ -1008,7 +1019,7 @@ class inst_t { operation_pipeline op_pipe; // code (uarch visible) identify the pipeline of // the operation (SP, SFU or MEM) mem_operation mem_op; // code (uarch visible) identify memory type - bool const_cache_operand; // has a load from constant memory as an operand + bool const_cache_operand; // has a load from constant memory as an operand _memory_op_t memory_op; // memory_op used by ptxplus unsigned num_operands; unsigned num_regs; // count vector operand as one register operand @@ -1052,11 +1063,20 @@ class warp_inst_t : public inst_t { // constructors warp_inst_t() { m_uid = 0; + m_streamID = (unsigned long long)-1; m_empty = true; m_config = NULL; + + // Ni: + m_is_ldgsts = false; + m_is_ldgdepbar = false; + m_is_depbar = false; + + m_depbar_group_no = 0; } warp_inst_t(const core_config *config) { m_uid = 0; + m_streamID = (unsigned long long)-1; assert(config->warp_size <= MAX_WARP_SIZE); m_config = config; m_empty = true; @@ -1067,6 +1087,13 @@ class warp_inst_t : public inst_t { m_is_printf = false; m_is_cdp = 0; should_do_atomic = true; + + // Ni: + m_is_ldgsts = false; + m_is_ldgdepbar = false; + m_is_depbar = false; + + m_depbar_group_no = 0; } virtual ~warp_inst_t() {} @@ -1077,7 +1104,8 @@ class warp_inst_t : public inst_t { void clear() { m_empty = true; } void issue(const active_mask_t &mask, unsigned warp_id, - unsigned long long cycle, int dynamic_warp_id, int sch_id); + unsigned long long cycle, int dynamic_warp_id, int sch_id, + unsigned long long streamID); const active_mask_t &get_active_mask() const { return m_warp_active_mask; } void completed(unsigned long long cycle) @@ -1155,7 +1183,7 @@ class warp_inst_t : public inst_t { // accessors virtual void print_insn(FILE *fp) const { - fprintf(fp, " [inst @ pc=0x%04x] ", pc); + fprintf(fp, " [inst @ pc=0x%04llx] ", pc); for (int i = (int)m_config->warp_size - 1; i >= 0; i--) fprintf(fp, "%c", ((m_warp_active_mask[i]) ? '1' : '0')); } @@ -1205,11 +1233,13 @@ class warp_inst_t : public inst_t { void print(FILE *fout) const; unsigned get_uid() const { return m_uid; } + unsigned long long get_streamID() const { return m_streamID; } unsigned get_schd_id() const { return m_scheduler_id; } active_mask_t get_warp_active_mask() const { return m_warp_active_mask; } protected: unsigned m_uid; + unsigned long long m_streamID; bool m_empty; bool m_cache_hit; unsigned long long issue_cycle; @@ -1249,6 +1279,13 @@ class warp_inst_t : public inst_t { // Jin: cdp support public: int m_is_cdp; + + // Ni: add boolean to indicate whether the instruction is ldgsts + bool m_is_ldgsts; + bool m_is_ldgdepbar; + bool m_is_depbar; + + unsigned int m_depbar_group_no; }; void move_warp(warp_inst_t *&dst, warp_inst_t *&src); @@ -1384,7 +1421,7 @@ class register_set { assert(has_ready()); warp_inst_t **ready; ready = NULL; - unsigned reg_id; + unsigned reg_id = 0; for (unsigned i = 0; i < regs.size(); i++) { if (not regs[i]->empty()) { if (ready and (*ready)->get_uid() < regs[i]->get_uid()) { diff --git a/src/accelwattch/CMakeLists.txt b/src/accelwattch/CMakeLists.txt new file mode 100644 index 0000000..cb7dd71 --- /dev/null +++ b/src/accelwattch/CMakeLists.txt @@ -0,0 +1,46 @@ +set(GPGPUSIM_ACCELWATTCH_NTHREADS "4" CACHE STRING "Accelwattch MCPAT thread count") +add_library(accelwattch STATIC + cacti/Ucache.cc + XML_Parse.cc + cacti/arbiter.cc + cacti/area.cc + array.cc + cacti/bank.cc + cacti/basic_circuit.cc + basic_components.cc + cacti/cacti_interface.cc + cacti/component.cc + core.cc + cacti/crossbar.cc + cacti/decoder.cc + cacti/htree2.cc + interconnect.cc + cacti/io.cc + iocontrollers.cc + logic.cc + main.cc + cacti/mat.cc + memoryctrl.cc + noc.cc + cacti/nuca.cc + cacti/parameter.cc + processor.cc + cacti/router.cc + sharedcache.cc + cacti/subarray.cc + cacti/technology.cc + cacti/uca.cc + cacti/wire.cc + xmlParser.cc + gpgpu_sim_wrapper.cc) +target_include_directories(accelwattch PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(accelwattch PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/cacti) +# Compile options +target_compile_options(accelwattch PRIVATE "-Wno-unknown-pragmas") +if($<CONFIG:Debug>) + target_compile_definitions(NTHREADS=1) +else() + target_compile_options(accelwattch PRIVATE "-msse2;-mfpmath=sse") + target_compile_definitions(accelwattch PRIVATE -DNTHREADS=${GPGPUSIM_ACCELWATTCH_NTHREADS}) +endif() +target_link_options(accelwattch PRIVATE "-lm;-lpthread;-lz")
\ No newline at end of file diff --git a/src/accelwattch/XML_Parse.cc b/src/accelwattch/XML_Parse.cc index eaec748..801de6f 100644 --- a/src/accelwattch/XML_Parse.cc +++ b/src/accelwattch/XML_Parse.cc @@ -30,14 +30,13 @@ ***************************************************************************/
/********************************************************************
* Modified by:
- * Jingwen Leng, University of Texas, Austin
- * Syed Gilani, University of Wisconsin–Madison
+ * Jingwen Leng, University of Texas, Austin
+ * Syed Gilani, University of Wisconsin–Madison
* Tayler Hetherington, University of British Columbia
* Ahmed ElTantawy, University of British Columbia
* Vijay Kandiah, Northwestern University
********************************************************************/
-
#include "XML_Parse.h"
#include <stdio.h>
#include <string>
@@ -45,14 +44,18 @@ using namespace std;
-const char * perf_count_label[] = {
- "TOT_INST,", "FP_INT,", "IC_H,", "IC_M,", "DC_RH,", "DC_RM,", "DC_WH,", "DC_WM,",
- "TC_H,", "TC_M,", "CC_H,", "CC_M,", "SHRD_ACC,", "REG_RD,", "REG_WR,", "NON_REG_OPs,",
- "INT_ACC,", "FPU_ACC,", "DPU_ACC,", "INT_MUL24_ACC,", "INT_MUL32_ACC,", "INT_MUL_ACC,","INT_DIV_ACC,",
- "FP_MUL_ACC,", "FP_DIV_ACC,", "FP_SQRT_ACC,", "FP_LG_ACC,", "FP_SIN_ACC,", "FP_EXP_ACC,", "DP_MUL_ACC,",
- "DP_DIV_ACC,", "TENSOR_ACC,", "TEX_ACC,", "MEM_RD,","MEM_WR,", "MEM_PRE,", "L2_RH,", "L2_RM,", "L2_WH,",
- "L2_WM,", "NOC_A,", "PIPE_A,", "IDLE_CORE_N,", "constant_power"};
-
+const char* perf_count_label[] = {
+ "TOT_INST,", "FP_INT,", "IC_H,", "IC_M,",
+ "DC_RH,", "DC_RM,", "DC_WH,", "DC_WM,",
+ "TC_H,", "TC_M,", "CC_H,", "CC_M,",
+ "SHRD_ACC,", "REG_RD,", "REG_WR,", "NON_REG_OPs,",
+ "INT_ACC,", "FPU_ACC,", "DPU_ACC,", "INT_MUL24_ACC,",
+ "INT_MUL32_ACC,", "INT_MUL_ACC,", "INT_DIV_ACC,", "FP_MUL_ACC,",
+ "FP_DIV_ACC,", "FP_SQRT_ACC,", "FP_LG_ACC,", "FP_SIN_ACC,",
+ "FP_EXP_ACC,", "DP_MUL_ACC,", "DP_DIV_ACC,", "TENSOR_ACC,",
+ "TEX_ACC,", "MEM_RD,", "MEM_WR,", "MEM_PRE,",
+ "L2_RH,", "L2_RM,", "L2_WH,", "L2_WM,",
+ "NOC_A,", "PIPE_A,", "IDLE_CORE_N,", "constant_power"};
void ParseXML::parse(char* filepath) {
unsigned int i, j, k, m, n;
@@ -171,8 +174,6 @@ void ParseXML::parse(char* filepath) { continue;
}
-
-
if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
"static_cat1_flane") == 0) {
sys.static_cat1_flane =
@@ -355,7 +356,6 @@ void ParseXML::parse(char* filepath) { continue;
}
-
if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
"target_chip_area") == 0) {
sys.target_chip_area =
@@ -615,106 +615,106 @@ void ParseXML::parse(char* filepath) { atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "INT_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "INT_ACC") == 0) {
sys.scaling_coefficients[INT_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "FP_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "FP_ACC") == 0) {
sys.scaling_coefficients[FP_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "DP_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "DP_ACC") == 0) {
sys.scaling_coefficients[DP_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "INT_MUL24_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "INT_MUL24_ACC") == 0) {
sys.scaling_coefficients[INT_MUL24_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "INT_MUL32_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "INT_MUL32_ACC") == 0) {
sys.scaling_coefficients[INT_MUL32_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "INT_MUL_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "INT_MUL_ACC") == 0) {
sys.scaling_coefficients[INT_MUL_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "INT_DIV_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "INT_DIV_ACC") == 0) {
sys.scaling_coefficients[INT_DIV_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "FP_MUL_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "FP_MUL_ACC") == 0) {
sys.scaling_coefficients[FP_MUL_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "FP_DIV_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "FP_DIV_ACC") == 0) {
sys.scaling_coefficients[FP_DIV_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "FP_SQRT_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "FP_SQRT_ACC") == 0) {
sys.scaling_coefficients[FP_SQRT_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "FP_LG_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "FP_LG_ACC") == 0) {
sys.scaling_coefficients[FP_LG_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "FP_SIN_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "FP_SIN_ACC") == 0) {
sys.scaling_coefficients[FP_SIN_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "FP_EXP_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "FP_EXP_ACC") == 0) {
sys.scaling_coefficients[FP_EXP_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "DP_MUL_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "DP_MUL_ACC") == 0) {
sys.scaling_coefficients[DP_MUL_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "DP_DIV_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "DP_DIV_ACC") == 0) {
sys.scaling_coefficients[DP_DIV_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "TENSOR_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "TENSOR_ACC") == 0) {
sys.scaling_coefficients[TENSOR_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
- if (strcmp(xNode2.getChildNode("param",i).getAttribute("name"),
- "TEX_ACC")==0) {
+ if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
+ "TEX_ACC") == 0) {
sys.scaling_coefficients[TEX_ACC] =
- atof(xNode2.getChildNode("param",i).getAttribute("value"));
+ atof(xNode2.getChildNode("param", i).getAttribute("value"));
continue;
}
if (strcmp(xNode2.getChildNode("param", i).getAttribute("name"),
diff --git a/src/accelwattch/XML_Parse.h b/src/accelwattch/XML_Parse.h index c82359f..176b82f 100644 --- a/src/accelwattch/XML_Parse.h +++ b/src/accelwattch/XML_Parse.h @@ -30,8 +30,8 @@ ***************************************************************************/
/********************************************************************
* Modified by:
- * Jingwen Leng, University of Texas, Austin
- * Syed Gilani, University of Wisconsin–Madison
+ * Jingwen Leng, University of Texas, Austin
+ * Syed Gilani, University of Wisconsin–Madison
* Tayler Hetherington, University of British Columbia
* Ahmed ElTantawy, University of British Columbia
* Vijay Kandiah, Northwestern University
@@ -70,7 +70,7 @@ ToXMLStringTool tx,tx2; extern const char* perf_count_label[];
enum perf_count_t {
- TOT_INST=0,
+ TOT_INST = 0,
FP_INT,
IC_H,
IC_M,
@@ -86,23 +86,23 @@ enum perf_count_t { REG_RD,
REG_WR,
NON_REG_OPs,
- INT_ACC, //SPU
- FP_ACC, //FPU
- DP_ACC, //FPU
- INT_MUL24_ACC, //SFU
- INT_MUL32_ACC, //SFU
- INT_MUL_ACC, //SFU
- INT_DIV_ACC, //SFU
- FP_MUL_ACC, //SFU
- FP_DIV_ACC, //SFU
- FP_SQRT_ACC, //SFU
- FP_LG_ACC, //SFU
- FP_SIN_ACC, //SFU
- FP_EXP_ACC, //SFU
- DP_MUL_ACC, //SFU
- DP_DIV_ACC, //SFU
- TENSOR_ACC, //SFU
- TEX_ACC, //SFU
+ INT_ACC, // SPU
+ FP_ACC, // FPU
+ DP_ACC, // FPU
+ INT_MUL24_ACC, // SFU
+ INT_MUL32_ACC, // SFU
+ INT_MUL_ACC, // SFU
+ INT_DIV_ACC, // SFU
+ FP_MUL_ACC, // SFU
+ FP_DIV_ACC, // SFU
+ FP_SQRT_ACC, // SFU
+ FP_LG_ACC, // SFU
+ FP_SIN_ACC, // SFU
+ FP_EXP_ACC, // SFU
+ DP_MUL_ACC, // SFU
+ DP_DIV_ACC, // SFU
+ TENSOR_ACC, // SFU
+ TEX_ACC, // SFU
MEM_RD,
MEM_WR,
MEM_PRE,
diff --git a/src/accelwattch/gpgpu_sim_wrapper.cc b/src/accelwattch/gpgpu_sim_wrapper.cc index 67d9daa..4883c7c 100644 --- a/src/accelwattch/gpgpu_sim_wrapper.cc +++ b/src/accelwattch/gpgpu_sim_wrapper.cc @@ -1,16 +1,17 @@ -// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington, Ahmed ElTantawy, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington, Ahmed ElTantawy, +// Vijay Kandiah, Nikos Hardavellas The University of British Columbia, +// Northwestern University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -33,14 +34,16 @@ #define SFU_BASE_POWER 0 static const char* pwr_cmp_label[] = { - "IBP,", "ICP,", "DCP,", "TCP,", "CCP,", "SHRDP,", "RFP,", "INTP,", - "FPUP,", "DPUP,", "INT_MUL24P,", "INT_MUL32P,", "INT_MULP,", "INT_DIVP,", - "FP_MULP,", "FP_DIVP,", "FP_SQRTP,", "FP_LGP,", "FP_SINP,", "FP_EXP,", - "DP_MULP,", "DP_DIVP,", "TENSORP,", "TEXP,", "SCHEDP,", "L2CP,", "MCP,", "NOCP,", - "DRAMP,", "PIPEP,", "IDLE_COREP,", "CONSTP", "STATICP"}; + "IBP,", "ICP,", "DCP,", "TCP,", "CCP,", + "SHRDP,", "RFP,", "INTP,", "FPUP,", "DPUP,", + "INT_MUL24P,", "INT_MUL32P,", "INT_MULP,", "INT_DIVP,", "FP_MULP,", + "FP_DIVP,", "FP_SQRTP,", "FP_LGP,", "FP_SINP,", "FP_EXP,", + "DP_MULP,", "DP_DIVP,", "TENSORP,", "TEXP,", "SCHEDP,", + "L2CP,", "MCP,", "NOCP,", "DRAMP,", "PIPEP,", + "IDLE_COREP,", "CONSTP", "STATICP"}; enum pwr_cmp_t { - IBP=0, + IBP = 0, ICP, DCP, TCP, @@ -77,7 +80,8 @@ enum pwr_cmp_t { }; gpgpu_sim_wrapper::gpgpu_sim_wrapper(bool power_simulation_enabled, - char* xmlfile, int power_simulation_mode, bool dvfs_enabled) { + char* xmlfile, int power_simulation_mode, + bool dvfs_enabled) { kernel_sample_count = 0; total_sample_count = 0; @@ -142,7 +146,8 @@ bool gpgpu_sim_wrapper::sanity_check(double a, double b) { return false; } void gpgpu_sim_wrapper::init_mcpat_hw_mode(unsigned gpu_sim_cycle) { - p->sys.total_cycles = gpu_sim_cycle; //total simulated cycles for current kernel + p->sys.total_cycles = + gpu_sim_cycle; // total simulated cycles for current kernel } void gpgpu_sim_wrapper::init_mcpat( @@ -150,9 +155,9 @@ void gpgpu_sim_wrapper::init_mcpat( char* metric_trace_filename, char* steady_state_filename, bool power_sim_enabled, bool trace_enabled, bool steady_state_enabled, bool power_per_cycle_dump, double steady_power_deviation, - double steady_min_period, int zlevel, double init_val, - int stat_sample_freq, int power_sim_mode, bool dvfs_enabled, - unsigned clock_freq, unsigned num_shaders) { + double steady_min_period, int zlevel, double init_val, int stat_sample_freq, + int power_sim_mode, bool dvfs_enabled, unsigned clock_freq, + unsigned num_shaders) { // Write File Headers for (-metrics trace, -power trace) reset_counters(); @@ -382,10 +387,7 @@ void gpgpu_sim_wrapper::set_l2cache_power(double read_hits, double read_misses, sample_perf_counters[L2_WM] = write_misses; } -void gpgpu_sim_wrapper::set_num_cores(double num_core) { - - num_cores = num_core; -} +void gpgpu_sim_wrapper::set_num_cores(double num_core) { num_cores = num_core; } void gpgpu_sim_wrapper::set_idle_core_power(double num_idle_core) { p->sys.num_idle_cores = num_idle_core; @@ -411,29 +413,25 @@ void gpgpu_sim_wrapper::set_mem_ctrl_power(double reads, double writes, sample_perf_counters[MEM_PRE] = dram_precharge; } - void gpgpu_sim_wrapper::set_model_voltage(double model_voltage) { - modeled_chip_voltage = model_voltage; + modeled_chip_voltage = model_voltage; } - void gpgpu_sim_wrapper::set_exec_unit_power(double fpu_accesses, double ialu_accesses, double sfu_accesses) { p->sys.core[0].fpu_accesses = fpu_accesses; tot_fpu_accesses = fpu_accesses; - //Integer ALU (not present in Tesla) + // Integer ALU (not present in Tesla) p->sys.core[0].ialu_accesses = ialu_accesses; - //Sfu accesses + // Sfu accesses p->sys.core[0].mul_accesses = sfu_accesses; tot_sfu_accesses = sfu_accesses; } -PowerscalingCoefficients * gpgpu_sim_wrapper::get_scaling_coeffs() -{ - - PowerscalingCoefficients * scalingCoeffs = new PowerscalingCoefficients(); +PowerscalingCoefficients* gpgpu_sim_wrapper::get_scaling_coeffs() { + PowerscalingCoefficients* scalingCoeffs = new PowerscalingCoefficients(); scalingCoeffs->int_coeff = p->sys.scaling_coefficients[INT_ACC]; scalingCoeffs->int_mul_coeff = p->sys.scaling_coefficients[INT_MUL_ACC]; @@ -453,68 +451,55 @@ PowerscalingCoefficients * gpgpu_sim_wrapper::get_scaling_coeffs() scalingCoeffs->tensor_coeff = p->sys.scaling_coefficients[TENSOR_ACC]; scalingCoeffs->tex_coeff = p->sys.scaling_coefficients[TEX_ACC]; return scalingCoeffs; - } -void gpgpu_sim_wrapper::set_int_accesses(double ialu_accesses, - double imul24_accesses, - double imul32_accesses, - double imul_accesses, - double idiv_accesses) -{ - - sample_perf_counters[INT_ACC]=ialu_accesses; - sample_perf_counters[INT_MUL24_ACC]=imul24_accesses; - sample_perf_counters[INT_MUL32_ACC]=imul32_accesses; - sample_perf_counters[INT_MUL_ACC]=imul_accesses; - sample_perf_counters[INT_DIV_ACC]=idiv_accesses; +void gpgpu_sim_wrapper::set_int_accesses(double ialu_accesses, + double imul24_accesses, + double imul32_accesses, + double imul_accesses, + double idiv_accesses) { + sample_perf_counters[INT_ACC] = ialu_accesses; + sample_perf_counters[INT_MUL24_ACC] = imul24_accesses; + sample_perf_counters[INT_MUL32_ACC] = imul32_accesses; + sample_perf_counters[INT_MUL_ACC] = imul_accesses; + sample_perf_counters[INT_DIV_ACC] = idiv_accesses; } -void gpgpu_sim_wrapper::set_dp_accesses(double dpu_accesses, - double dpmul_accesses, - double dpdiv_accesses) -{ - sample_perf_counters[DP_ACC]=dpu_accesses; - sample_perf_counters[DP_MUL_ACC]=dpmul_accesses; - sample_perf_counters[DP_DIV_ACC]=dpdiv_accesses; +void gpgpu_sim_wrapper::set_dp_accesses(double dpu_accesses, + double dpmul_accesses, + double dpdiv_accesses) { + sample_perf_counters[DP_ACC] = dpu_accesses; + sample_perf_counters[DP_MUL_ACC] = dpmul_accesses; + sample_perf_counters[DP_DIV_ACC] = dpdiv_accesses; } -void gpgpu_sim_wrapper::set_fp_accesses(double fpu_accesses, - double fpmul_accesses, - double fpdiv_accesses) -{ - sample_perf_counters[FP_ACC]=fpu_accesses; - sample_perf_counters[FP_MUL_ACC]=fpmul_accesses; - sample_perf_counters[FP_DIV_ACC]=fpdiv_accesses; +void gpgpu_sim_wrapper::set_fp_accesses(double fpu_accesses, + double fpmul_accesses, + double fpdiv_accesses) { + sample_perf_counters[FP_ACC] = fpu_accesses; + sample_perf_counters[FP_MUL_ACC] = fpmul_accesses; + sample_perf_counters[FP_DIV_ACC] = fpdiv_accesses; } -void gpgpu_sim_wrapper::set_trans_accesses(double sqrt_accesses, - double log_accesses, - double sin_accesses, - double exp_accesses) -{ - - sample_perf_counters[FP_SQRT_ACC]=sqrt_accesses; - sample_perf_counters[FP_LG_ACC]=log_accesses; - sample_perf_counters[FP_SIN_ACC]=sin_accesses; - sample_perf_counters[FP_EXP_ACC]=exp_accesses; - +void gpgpu_sim_wrapper::set_trans_accesses(double sqrt_accesses, + double log_accesses, + double sin_accesses, + double exp_accesses) { + sample_perf_counters[FP_SQRT_ACC] = sqrt_accesses; + sample_perf_counters[FP_LG_ACC] = log_accesses; + sample_perf_counters[FP_SIN_ACC] = sin_accesses; + sample_perf_counters[FP_EXP_ACC] = exp_accesses; } -void gpgpu_sim_wrapper::set_tensor_accesses(double tensor_accesses) -{ - sample_perf_counters[TENSOR_ACC]=tensor_accesses; - +void gpgpu_sim_wrapper::set_tensor_accesses(double tensor_accesses) { + sample_perf_counters[TENSOR_ACC] = tensor_accesses; } -void gpgpu_sim_wrapper::set_tex_accesses(double tex_accesses) -{ - sample_perf_counters[TEX_ACC]=tex_accesses; - +void gpgpu_sim_wrapper::set_tex_accesses(double tex_accesses) { + sample_perf_counters[TEX_ACC] = tex_accesses; } -void gpgpu_sim_wrapper::set_avg_active_threads(float active_threads) -{ +void gpgpu_sim_wrapper::set_avg_active_threads(float active_threads) { avg_threads_per_warp = (unsigned)ceil(active_threads); avg_threads_per_warp_tot += active_threads; } @@ -536,7 +521,8 @@ void gpgpu_sim_wrapper::power_metrics_calculations() { kernel_sample_count++; // Current sample power - double sample_power = proc->rt_power.readOp.dynamic + sample_cmp_pwr[CONSTP] + sample_cmp_pwr[STATICP]; + double sample_power = proc->rt_power.readOp.dynamic + sample_cmp_pwr[CONSTP] + + sample_cmp_pwr[STATICP]; // double sample_power; // for(unsigned i=0; i<num_pwr_cmps; i++){ // sample_power+=sample_cmp_pwr[i]; //fix for dvfs @@ -602,371 +588,503 @@ void gpgpu_sim_wrapper::print_trace_files() { close_files(); } -void gpgpu_sim_wrapper::update_coefficients() -{ +void gpgpu_sim_wrapper::update_coefficients() { + initpower_coeff[FP_INT] = proc->cores[0]->get_coefficient_fpint_insts(); + effpower_coeff[FP_INT] = + initpower_coeff[FP_INT] * p->sys.scaling_coefficients[FP_INT]; - initpower_coeff[FP_INT]=proc->cores[0]->get_coefficient_fpint_insts(); - effpower_coeff[FP_INT]=initpower_coeff[FP_INT] * p->sys.scaling_coefficients[FP_INT]; + initpower_coeff[TOT_INST] = proc->cores[0]->get_coefficient_tot_insts(); + effpower_coeff[TOT_INST] = + initpower_coeff[TOT_INST] * p->sys.scaling_coefficients[TOT_INST]; - initpower_coeff[TOT_INST]=proc->cores[0]->get_coefficient_tot_insts(); - effpower_coeff[TOT_INST]=initpower_coeff[TOT_INST] * p->sys.scaling_coefficients[TOT_INST]; + initpower_coeff[REG_RD] = + proc->cores[0]->get_coefficient_regreads_accesses() * + (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); + initpower_coeff[REG_WR] = + proc->cores[0]->get_coefficient_regwrites_accesses() * + (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); + initpower_coeff[NON_REG_OPs] = + proc->cores[0]->get_coefficient_noregfileops_accesses() * + (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); + effpower_coeff[REG_RD] = + initpower_coeff[REG_RD] * p->sys.scaling_coefficients[REG_RD]; + effpower_coeff[REG_WR] = + initpower_coeff[REG_WR] * p->sys.scaling_coefficients[REG_WR]; + effpower_coeff[NON_REG_OPs] = + initpower_coeff[NON_REG_OPs] * p->sys.scaling_coefficients[NON_REG_OPs]; - initpower_coeff[REG_RD]=proc->cores[0]->get_coefficient_regreads_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); - initpower_coeff[REG_WR]=proc->cores[0]->get_coefficient_regwrites_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); - initpower_coeff[NON_REG_OPs]=proc->cores[0]->get_coefficient_noregfileops_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); - effpower_coeff[REG_RD]=initpower_coeff[REG_RD]*p->sys.scaling_coefficients[REG_RD]; - effpower_coeff[REG_WR]=initpower_coeff[REG_WR]*p->sys.scaling_coefficients[REG_WR]; - effpower_coeff[NON_REG_OPs]=initpower_coeff[NON_REG_OPs]*p->sys.scaling_coefficients[NON_REG_OPs]; + initpower_coeff[IC_H] = proc->cores[0]->get_coefficient_icache_hits(); + initpower_coeff[IC_M] = proc->cores[0]->get_coefficient_icache_misses(); + effpower_coeff[IC_H] = + initpower_coeff[IC_H] * p->sys.scaling_coefficients[IC_H]; + effpower_coeff[IC_M] = + initpower_coeff[IC_M] * p->sys.scaling_coefficients[IC_M]; - initpower_coeff[IC_H]=proc->cores[0]->get_coefficient_icache_hits(); - initpower_coeff[IC_M]=proc->cores[0]->get_coefficient_icache_misses(); - effpower_coeff[IC_H]=initpower_coeff[IC_H]*p->sys.scaling_coefficients[IC_H]; - effpower_coeff[IC_M]=initpower_coeff[IC_M]*p->sys.scaling_coefficients[IC_M]; + initpower_coeff[CC_H] = (proc->cores[0]->get_coefficient_ccache_readhits() + + proc->get_coefficient_readcoalescing()); + initpower_coeff[CC_M] = (proc->cores[0]->get_coefficient_ccache_readmisses() + + proc->get_coefficient_readcoalescing()); + effpower_coeff[CC_H] = + initpower_coeff[CC_H] * p->sys.scaling_coefficients[CC_H]; + effpower_coeff[CC_M] = + initpower_coeff[CC_M] * p->sys.scaling_coefficients[CC_M]; - initpower_coeff[CC_H]=(proc->cores[0]->get_coefficient_ccache_readhits()+proc->get_coefficient_readcoalescing()); - initpower_coeff[CC_M]=(proc->cores[0]->get_coefficient_ccache_readmisses()+proc->get_coefficient_readcoalescing()); - effpower_coeff[CC_H]=initpower_coeff[CC_H]*p->sys.scaling_coefficients[CC_H]; - effpower_coeff[CC_M]=initpower_coeff[CC_M]*p->sys.scaling_coefficients[CC_M]; + initpower_coeff[TC_H] = (proc->cores[0]->get_coefficient_tcache_readhits() + + proc->get_coefficient_readcoalescing()); + initpower_coeff[TC_M] = (proc->cores[0]->get_coefficient_tcache_readmisses() + + proc->get_coefficient_readcoalescing()); + effpower_coeff[TC_H] = + initpower_coeff[TC_H] * p->sys.scaling_coefficients[TC_H]; + effpower_coeff[TC_M] = + initpower_coeff[TC_M] * p->sys.scaling_coefficients[TC_M]; - initpower_coeff[TC_H]=(proc->cores[0]->get_coefficient_tcache_readhits()+proc->get_coefficient_readcoalescing()); - initpower_coeff[TC_M]=(proc->cores[0]->get_coefficient_tcache_readmisses()+proc->get_coefficient_readcoalescing()); - effpower_coeff[TC_H]=initpower_coeff[TC_H]*p->sys.scaling_coefficients[TC_H]; - effpower_coeff[TC_M]=initpower_coeff[TC_M]*p->sys.scaling_coefficients[TC_M]; + initpower_coeff[SHRD_ACC] = + proc->cores[0]->get_coefficient_sharedmemory_readhits(); + effpower_coeff[SHRD_ACC] = + initpower_coeff[SHRD_ACC] * p->sys.scaling_coefficients[SHRD_ACC]; - initpower_coeff[SHRD_ACC]=proc->cores[0]->get_coefficient_sharedmemory_readhits(); - effpower_coeff[SHRD_ACC]=initpower_coeff[SHRD_ACC]*p->sys.scaling_coefficients[SHRD_ACC]; + initpower_coeff[DC_RH] = (proc->cores[0]->get_coefficient_dcache_readhits() + + proc->get_coefficient_readcoalescing()); + initpower_coeff[DC_RM] = + (proc->cores[0]->get_coefficient_dcache_readmisses() + + proc->get_coefficient_readcoalescing()); + initpower_coeff[DC_WH] = (proc->cores[0]->get_coefficient_dcache_writehits() + + proc->get_coefficient_writecoalescing()); + initpower_coeff[DC_WM] = + (proc->cores[0]->get_coefficient_dcache_writemisses() + + proc->get_coefficient_writecoalescing()); + effpower_coeff[DC_RH] = + initpower_coeff[DC_RH] * p->sys.scaling_coefficients[DC_RH]; + effpower_coeff[DC_RM] = + initpower_coeff[DC_RM] * p->sys.scaling_coefficients[DC_RM]; + effpower_coeff[DC_WH] = + initpower_coeff[DC_WH] * p->sys.scaling_coefficients[DC_WH]; + effpower_coeff[DC_WM] = + initpower_coeff[DC_WM] * p->sys.scaling_coefficients[DC_WM]; - initpower_coeff[DC_RH]=(proc->cores[0]->get_coefficient_dcache_readhits() + proc->get_coefficient_readcoalescing()); - initpower_coeff[DC_RM]=(proc->cores[0]->get_coefficient_dcache_readmisses() + proc->get_coefficient_readcoalescing()); - initpower_coeff[DC_WH]=(proc->cores[0]->get_coefficient_dcache_writehits() + proc->get_coefficient_writecoalescing()); - initpower_coeff[DC_WM]=(proc->cores[0]->get_coefficient_dcache_writemisses() + proc->get_coefficient_writecoalescing()); - effpower_coeff[DC_RH]=initpower_coeff[DC_RH]*p->sys.scaling_coefficients[DC_RH]; - effpower_coeff[DC_RM]=initpower_coeff[DC_RM]*p->sys.scaling_coefficients[DC_RM]; - effpower_coeff[DC_WH]=initpower_coeff[DC_WH]*p->sys.scaling_coefficients[DC_WH]; - effpower_coeff[DC_WM]=initpower_coeff[DC_WM]*p->sys.scaling_coefficients[DC_WM]; + initpower_coeff[L2_RH] = proc->get_coefficient_l2_read_hits(); + initpower_coeff[L2_RM] = proc->get_coefficient_l2_read_misses(); + initpower_coeff[L2_WH] = proc->get_coefficient_l2_write_hits(); + initpower_coeff[L2_WM] = proc->get_coefficient_l2_write_misses(); + effpower_coeff[L2_RH] = + initpower_coeff[L2_RH] * p->sys.scaling_coefficients[L2_RH]; + effpower_coeff[L2_RM] = + initpower_coeff[L2_RM] * p->sys.scaling_coefficients[L2_RM]; + effpower_coeff[L2_WH] = + initpower_coeff[L2_WH] * p->sys.scaling_coefficients[L2_WH]; + effpower_coeff[L2_WM] = + initpower_coeff[L2_WM] * p->sys.scaling_coefficients[L2_WM]; - initpower_coeff[L2_RH]=proc->get_coefficient_l2_read_hits(); - initpower_coeff[L2_RM]=proc->get_coefficient_l2_read_misses(); - initpower_coeff[L2_WH]=proc->get_coefficient_l2_write_hits(); - initpower_coeff[L2_WM]=proc->get_coefficient_l2_write_misses(); - effpower_coeff[L2_RH]=initpower_coeff[L2_RH]*p->sys.scaling_coefficients[L2_RH]; - effpower_coeff[L2_RM]=initpower_coeff[L2_RM]*p->sys.scaling_coefficients[L2_RM]; - effpower_coeff[L2_WH]=initpower_coeff[L2_WH]*p->sys.scaling_coefficients[L2_WH]; - effpower_coeff[L2_WM]=initpower_coeff[L2_WM]*p->sys.scaling_coefficients[L2_WM]; + initpower_coeff[IDLE_CORE_N] = + p->sys.idle_core_power * proc->cores[0]->executionTime; + effpower_coeff[IDLE_CORE_N] = + initpower_coeff[IDLE_CORE_N] * p->sys.scaling_coefficients[IDLE_CORE_N]; - initpower_coeff[IDLE_CORE_N]=p->sys.idle_core_power * proc->cores[0]->executionTime; - effpower_coeff[IDLE_CORE_N]=initpower_coeff[IDLE_CORE_N]*p->sys.scaling_coefficients[IDLE_CORE_N]; + initpower_coeff[PIPE_A] = proc->cores[0]->get_coefficient_duty_cycle(); + effpower_coeff[PIPE_A] = + initpower_coeff[PIPE_A] * p->sys.scaling_coefficients[PIPE_A]; - initpower_coeff[PIPE_A]=proc->cores[0]->get_coefficient_duty_cycle(); - effpower_coeff[PIPE_A]=initpower_coeff[PIPE_A]*p->sys.scaling_coefficients[PIPE_A]; + initpower_coeff[MEM_RD] = proc->get_coefficient_mem_reads(); + initpower_coeff[MEM_WR] = proc->get_coefficient_mem_writes(); + initpower_coeff[MEM_PRE] = proc->get_coefficient_mem_pre(); + effpower_coeff[MEM_RD] = + initpower_coeff[MEM_RD] * p->sys.scaling_coefficients[MEM_RD]; + effpower_coeff[MEM_WR] = + initpower_coeff[MEM_WR] * p->sys.scaling_coefficients[MEM_WR]; + effpower_coeff[MEM_PRE] = + initpower_coeff[MEM_PRE] * p->sys.scaling_coefficients[MEM_PRE]; - initpower_coeff[MEM_RD]=proc->get_coefficient_mem_reads(); - initpower_coeff[MEM_WR]=proc->get_coefficient_mem_writes(); - initpower_coeff[MEM_PRE]=proc->get_coefficient_mem_pre(); - effpower_coeff[MEM_RD]=initpower_coeff[MEM_RD]*p->sys.scaling_coefficients[MEM_RD]; - effpower_coeff[MEM_WR]=initpower_coeff[MEM_WR]*p->sys.scaling_coefficients[MEM_WR]; - effpower_coeff[MEM_PRE]=initpower_coeff[MEM_PRE]*p->sys.scaling_coefficients[MEM_PRE]; - double fp_coeff = proc->cores[0]->get_coefficient_fpu_accesses(); double sfu_coeff = proc->cores[0]->get_coefficient_sfu_accesses(); - initpower_coeff[INT_ACC]= proc->cores[0]->get_coefficient_ialu_accesses()*(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); + initpower_coeff[INT_ACC] = + proc->cores[0]->get_coefficient_ialu_accesses() * + (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); - if(tot_fpu_accesses != 0){ - initpower_coeff[FP_ACC]= fp_coeff * sample_perf_counters[FP_ACC]/tot_fpu_accesses; - initpower_coeff[DP_ACC]= fp_coeff * sample_perf_counters[DP_ACC]/tot_fpu_accesses; - } - else{ - initpower_coeff[FP_ACC]= 0; - initpower_coeff[DP_ACC]= 0; + if (tot_fpu_accesses != 0) { + initpower_coeff[FP_ACC] = + fp_coeff * sample_perf_counters[FP_ACC] / tot_fpu_accesses; + initpower_coeff[DP_ACC] = + fp_coeff * sample_perf_counters[DP_ACC] / tot_fpu_accesses; + } else { + initpower_coeff[FP_ACC] = 0; + initpower_coeff[DP_ACC] = 0; } - if(tot_sfu_accesses != 0){ - initpower_coeff[INT_MUL24_ACC]= sfu_coeff * sample_perf_counters[INT_MUL24_ACC]/tot_sfu_accesses; - initpower_coeff[INT_MUL32_ACC]= sfu_coeff * sample_perf_counters[INT_MUL32_ACC]/tot_sfu_accesses; - initpower_coeff[INT_MUL_ACC]= sfu_coeff * sample_perf_counters[INT_MUL_ACC]/tot_sfu_accesses; - initpower_coeff[INT_DIV_ACC]= sfu_coeff * sample_perf_counters[INT_DIV_ACC]/tot_sfu_accesses; - initpower_coeff[DP_MUL_ACC]= sfu_coeff * sample_perf_counters[DP_MUL_ACC]/tot_sfu_accesses; - initpower_coeff[DP_DIV_ACC]= sfu_coeff * sample_perf_counters[DP_DIV_ACC]/tot_sfu_accesses; - initpower_coeff[FP_MUL_ACC]= sfu_coeff * sample_perf_counters[FP_MUL_ACC]/tot_sfu_accesses; - initpower_coeff[FP_DIV_ACC]= sfu_coeff * sample_perf_counters[FP_DIV_ACC]/tot_sfu_accesses; - initpower_coeff[FP_SQRT_ACC]= sfu_coeff * sample_perf_counters[FP_SQRT_ACC]/tot_sfu_accesses; - initpower_coeff[FP_LG_ACC]= sfu_coeff * sample_perf_counters[FP_LG_ACC]/tot_sfu_accesses; - initpower_coeff[FP_SIN_ACC]= sfu_coeff * sample_perf_counters[FP_SIN_ACC]/tot_sfu_accesses; - initpower_coeff[FP_EXP_ACC]= sfu_coeff * sample_perf_counters[FP_EXP_ACC]/tot_sfu_accesses; - initpower_coeff[TENSOR_ACC]= sfu_coeff * sample_perf_counters[TENSOR_ACC]/tot_sfu_accesses; - initpower_coeff[TEX_ACC]= sfu_coeff * sample_perf_counters[TEX_ACC]/tot_sfu_accesses; - } - else{ - initpower_coeff[INT_MUL24_ACC]= 0; - initpower_coeff[INT_MUL32_ACC]= 0; - initpower_coeff[INT_MUL_ACC]= 0; - initpower_coeff[INT_DIV_ACC]= 0; - initpower_coeff[DP_MUL_ACC]= 0; - initpower_coeff[DP_DIV_ACC]= 0; - initpower_coeff[FP_MUL_ACC]= 0; - initpower_coeff[FP_DIV_ACC]= 0; - initpower_coeff[FP_SQRT_ACC]= 0; - initpower_coeff[FP_LG_ACC]= 0; - initpower_coeff[FP_SIN_ACC]= 0; - initpower_coeff[FP_EXP_ACC]= 0; - initpower_coeff[TENSOR_ACC]= 0; - initpower_coeff[TEX_ACC]= 0; + if (tot_sfu_accesses != 0) { + initpower_coeff[INT_MUL24_ACC] = + sfu_coeff * sample_perf_counters[INT_MUL24_ACC] / tot_sfu_accesses; + initpower_coeff[INT_MUL32_ACC] = + sfu_coeff * sample_perf_counters[INT_MUL32_ACC] / tot_sfu_accesses; + initpower_coeff[INT_MUL_ACC] = + sfu_coeff * sample_perf_counters[INT_MUL_ACC] / tot_sfu_accesses; + initpower_coeff[INT_DIV_ACC] = + sfu_coeff * sample_perf_counters[INT_DIV_ACC] / tot_sfu_accesses; + initpower_coeff[DP_MUL_ACC] = + sfu_coeff * sample_perf_counters[DP_MUL_ACC] / tot_sfu_accesses; + initpower_coeff[DP_DIV_ACC] = + sfu_coeff * sample_perf_counters[DP_DIV_ACC] / tot_sfu_accesses; + initpower_coeff[FP_MUL_ACC] = + sfu_coeff * sample_perf_counters[FP_MUL_ACC] / tot_sfu_accesses; + initpower_coeff[FP_DIV_ACC] = + sfu_coeff * sample_perf_counters[FP_DIV_ACC] / tot_sfu_accesses; + initpower_coeff[FP_SQRT_ACC] = + sfu_coeff * sample_perf_counters[FP_SQRT_ACC] / tot_sfu_accesses; + initpower_coeff[FP_LG_ACC] = + sfu_coeff * sample_perf_counters[FP_LG_ACC] / tot_sfu_accesses; + initpower_coeff[FP_SIN_ACC] = + sfu_coeff * sample_perf_counters[FP_SIN_ACC] / tot_sfu_accesses; + initpower_coeff[FP_EXP_ACC] = + sfu_coeff * sample_perf_counters[FP_EXP_ACC] / tot_sfu_accesses; + initpower_coeff[TENSOR_ACC] = + sfu_coeff * sample_perf_counters[TENSOR_ACC] / tot_sfu_accesses; + initpower_coeff[TEX_ACC] = + sfu_coeff * sample_perf_counters[TEX_ACC] / tot_sfu_accesses; + } else { + initpower_coeff[INT_MUL24_ACC] = 0; + initpower_coeff[INT_MUL32_ACC] = 0; + initpower_coeff[INT_MUL_ACC] = 0; + initpower_coeff[INT_DIV_ACC] = 0; + initpower_coeff[DP_MUL_ACC] = 0; + initpower_coeff[DP_DIV_ACC] = 0; + initpower_coeff[FP_MUL_ACC] = 0; + initpower_coeff[FP_DIV_ACC] = 0; + initpower_coeff[FP_SQRT_ACC] = 0; + initpower_coeff[FP_LG_ACC] = 0; + initpower_coeff[FP_SIN_ACC] = 0; + initpower_coeff[FP_EXP_ACC] = 0; + initpower_coeff[TENSOR_ACC] = 0; + initpower_coeff[TEX_ACC] = 0; } - effpower_coeff[INT_ACC]= initpower_coeff[INT_ACC]; - effpower_coeff[FP_ACC]= initpower_coeff[FP_ACC]; - effpower_coeff[DP_ACC]= initpower_coeff[DP_ACC]; - effpower_coeff[INT_MUL24_ACC]= initpower_coeff[INT_MUL24_ACC]; - effpower_coeff[INT_MUL32_ACC]= initpower_coeff[INT_MUL32_ACC]; - effpower_coeff[INT_MUL_ACC]= initpower_coeff[INT_MUL_ACC]; - effpower_coeff[INT_DIV_ACC]= initpower_coeff[INT_DIV_ACC]; - effpower_coeff[DP_MUL_ACC]= initpower_coeff[DP_MUL_ACC]; - effpower_coeff[DP_DIV_ACC]= initpower_coeff[DP_DIV_ACC]; - effpower_coeff[FP_MUL_ACC]= initpower_coeff[FP_MUL_ACC]; - effpower_coeff[FP_DIV_ACC]= initpower_coeff[FP_DIV_ACC]; - effpower_coeff[FP_SQRT_ACC]= initpower_coeff[FP_SQRT_ACC]; - effpower_coeff[FP_LG_ACC]= initpower_coeff[FP_LG_ACC]; - effpower_coeff[FP_SIN_ACC]= initpower_coeff[FP_SIN_ACC]; - effpower_coeff[FP_EXP_ACC]= initpower_coeff[FP_EXP_ACC]; - effpower_coeff[TENSOR_ACC]= initpower_coeff[TENSOR_ACC]; - effpower_coeff[TEX_ACC]= initpower_coeff[TEX_ACC]; + effpower_coeff[INT_ACC] = initpower_coeff[INT_ACC]; + effpower_coeff[FP_ACC] = initpower_coeff[FP_ACC]; + effpower_coeff[DP_ACC] = initpower_coeff[DP_ACC]; + effpower_coeff[INT_MUL24_ACC] = initpower_coeff[INT_MUL24_ACC]; + effpower_coeff[INT_MUL32_ACC] = initpower_coeff[INT_MUL32_ACC]; + effpower_coeff[INT_MUL_ACC] = initpower_coeff[INT_MUL_ACC]; + effpower_coeff[INT_DIV_ACC] = initpower_coeff[INT_DIV_ACC]; + effpower_coeff[DP_MUL_ACC] = initpower_coeff[DP_MUL_ACC]; + effpower_coeff[DP_DIV_ACC] = initpower_coeff[DP_DIV_ACC]; + effpower_coeff[FP_MUL_ACC] = initpower_coeff[FP_MUL_ACC]; + effpower_coeff[FP_DIV_ACC] = initpower_coeff[FP_DIV_ACC]; + effpower_coeff[FP_SQRT_ACC] = initpower_coeff[FP_SQRT_ACC]; + effpower_coeff[FP_LG_ACC] = initpower_coeff[FP_LG_ACC]; + effpower_coeff[FP_SIN_ACC] = initpower_coeff[FP_SIN_ACC]; + effpower_coeff[FP_EXP_ACC] = initpower_coeff[FP_EXP_ACC]; + effpower_coeff[TENSOR_ACC] = initpower_coeff[TENSOR_ACC]; + effpower_coeff[TEX_ACC] = initpower_coeff[TEX_ACC]; - initpower_coeff[NOC_A]=proc->get_coefficient_noc_accesses(); - effpower_coeff[NOC_A]=initpower_coeff[NOC_A]*p->sys.scaling_coefficients[NOC_A]; + initpower_coeff[NOC_A] = proc->get_coefficient_noc_accesses(); + effpower_coeff[NOC_A] = + initpower_coeff[NOC_A] * p->sys.scaling_coefficients[NOC_A]; - //const_dynamic_power=proc->get_const_dynamic_power()/(proc->cores[0]->executionTime); + // const_dynamic_power=proc->get_const_dynamic_power()/(proc->cores[0]->executionTime); - for(unsigned i=0; i<num_perf_counters; i++){ - initpower_coeff[i]/=(proc->cores[0]->executionTime); - effpower_coeff[i]/=(proc->cores[0]->executionTime); + for (unsigned i = 0; i < num_perf_counters; i++) { + initpower_coeff[i] /= (proc->cores[0]->executionTime); + effpower_coeff[i] /= (proc->cores[0]->executionTime); } } -double gpgpu_sim_wrapper::calculate_static_power(){ - double int_accesses = initpower_coeff[INT_ACC] + initpower_coeff[INT_MUL24_ACC] + initpower_coeff[INT_MUL32_ACC] + initpower_coeff[INT_MUL_ACC] + initpower_coeff[INT_DIV_ACC]; - double int_add_accesses = initpower_coeff[INT_ACC]; - double int_mul_accesses = initpower_coeff[INT_MUL24_ACC] + initpower_coeff[INT_MUL32_ACC] + initpower_coeff[INT_MUL_ACC] + initpower_coeff[INT_DIV_ACC]; - double fp_accesses = initpower_coeff[FP_ACC] + initpower_coeff[FP_MUL_ACC] + initpower_coeff[FP_DIV_ACC]; - double dp_accesses = initpower_coeff[DP_ACC] + initpower_coeff[DP_MUL_ACC] + initpower_coeff[DP_DIV_ACC]; - double sfu_accesses = initpower_coeff[FP_SQRT_ACC] + initpower_coeff[FP_LG_ACC] + initpower_coeff[FP_SIN_ACC] + initpower_coeff[FP_EXP_ACC]; - double tensor_accesses = initpower_coeff[TENSOR_ACC]; - double tex_accesses = initpower_coeff[TEX_ACC]; - double total_static_power = 0.0; - double base_static_power = 0.0; - double lane_static_power = 0.0; - double per_active_core = (num_cores - num_idle_cores)/num_cores; - +double gpgpu_sim_wrapper::calculate_static_power() { + double int_accesses = + initpower_coeff[INT_ACC] + initpower_coeff[INT_MUL24_ACC] + + initpower_coeff[INT_MUL32_ACC] + initpower_coeff[INT_MUL_ACC] + + initpower_coeff[INT_DIV_ACC]; + double int_add_accesses = initpower_coeff[INT_ACC]; + double int_mul_accesses = + initpower_coeff[INT_MUL24_ACC] + initpower_coeff[INT_MUL32_ACC] + + initpower_coeff[INT_MUL_ACC] + initpower_coeff[INT_DIV_ACC]; + double fp_accesses = initpower_coeff[FP_ACC] + initpower_coeff[FP_MUL_ACC] + + initpower_coeff[FP_DIV_ACC]; + double dp_accesses = initpower_coeff[DP_ACC] + initpower_coeff[DP_MUL_ACC] + + initpower_coeff[DP_DIV_ACC]; + double sfu_accesses = + initpower_coeff[FP_SQRT_ACC] + initpower_coeff[FP_LG_ACC] + + initpower_coeff[FP_SIN_ACC] + initpower_coeff[FP_EXP_ACC]; + double tensor_accesses = initpower_coeff[TENSOR_ACC]; + double tex_accesses = initpower_coeff[TEX_ACC]; + double total_static_power = 0.0; + double base_static_power = 0.0; + double lane_static_power = 0.0; + double per_active_core = (num_cores - num_idle_cores) / num_cores; - double l1_accesses = initpower_coeff[DC_RH] + initpower_coeff[DC_RM] + initpower_coeff[DC_WH] + initpower_coeff[DC_WM]; - double l2_accesses = initpower_coeff[L2_RH] + initpower_coeff[L2_RM] + initpower_coeff[L2_WH] + initpower_coeff[L2_WM]; - double shared_accesses = initpower_coeff[SHRD_ACC]; + double l1_accesses = initpower_coeff[DC_RH] + initpower_coeff[DC_RM] + + initpower_coeff[DC_WH] + initpower_coeff[DC_WM]; + double l2_accesses = initpower_coeff[L2_RH] + initpower_coeff[L2_RM] + + initpower_coeff[L2_WH] + initpower_coeff[L2_WM]; + double shared_accesses = initpower_coeff[SHRD_ACC]; + if (avg_threads_per_warp == + 0) { // no functional unit threads, check for memory or a 'LIGHT_SM' + if (l1_accesses != 0.0) + return (p->sys.static_l1_flane * per_active_core); + else if (shared_accesses != 0.0) + return (p->sys.static_shared_flane * per_active_core); + else if (l2_accesses != 0.0) + return (p->sys.static_l2_flane * per_active_core); + else // LIGHT_SM + return (p->sys.static_light_flane * + per_active_core); // return LIGHT_SM base static power + } - if(avg_threads_per_warp == 0){ //no functional unit threads, check for memory or a 'LIGHT_SM' - if(l1_accesses != 0.0) - return (p->sys.static_l1_flane*per_active_core); - else if(shared_accesses != 0.0) - return (p->sys.static_shared_flane*per_active_core); - else if(l2_accesses != 0.0) - return (p->sys.static_l2_flane*per_active_core); - else //LIGHT_SM - return (p->sys.static_light_flane*per_active_core); //return LIGHT_SM base static power - } - - /* using a linear model for thread divergence */ - if((int_accesses != 0.0) && (fp_accesses != 0.0) && (dp_accesses != 0.0) && (sfu_accesses == 0.0) && (tensor_accesses == 0.0) && (tex_accesses == 0.0)){ - /* INT_FP_DP */ - base_static_power = p->sys.static_cat3_flane; - lane_static_power = p->sys.static_cat3_addlane; - } + /* using a linear model for thread divergence */ + if ((int_accesses != 0.0) && (fp_accesses != 0.0) && (dp_accesses != 0.0) && + (sfu_accesses == 0.0) && (tensor_accesses == 0.0) && + (tex_accesses == 0.0)) { + /* INT_FP_DP */ + base_static_power = p->sys.static_cat3_flane; + lane_static_power = p->sys.static_cat3_addlane; + } - else if((int_accesses != 0.0) && (fp_accesses != 0.0) && (dp_accesses == 0.0) && (sfu_accesses == 0.0) && (tensor_accesses != 0.0) && (tex_accesses == 0.0)){ - /* INT_FP_TENSOR */ - base_static_power = p->sys.static_cat6_flane; - lane_static_power = p->sys.static_cat6_addlane; - } + else if ((int_accesses != 0.0) && (fp_accesses != 0.0) && + (dp_accesses == 0.0) && (sfu_accesses == 0.0) && + (tensor_accesses != 0.0) && (tex_accesses == 0.0)) { + /* INT_FP_TENSOR */ + base_static_power = p->sys.static_cat6_flane; + lane_static_power = p->sys.static_cat6_addlane; + } - else if((int_accesses != 0.0) && (fp_accesses != 0.0) && (dp_accesses == 0.0) && (sfu_accesses != 0.0) && (tensor_accesses == 0.0) && (tex_accesses == 0.0)){ - /* INT_FP_SFU */ - base_static_power = p->sys.static_cat4_flane; - lane_static_power = p->sys.static_cat4_addlane; - } + else if ((int_accesses != 0.0) && (fp_accesses != 0.0) && + (dp_accesses == 0.0) && (sfu_accesses != 0.0) && + (tensor_accesses == 0.0) && (tex_accesses == 0.0)) { + /* INT_FP_SFU */ + base_static_power = p->sys.static_cat4_flane; + lane_static_power = p->sys.static_cat4_addlane; + } - else if((int_accesses != 0.0) && (fp_accesses != 0.0) && (dp_accesses == 0.0) && (sfu_accesses == 0.0) && (tensor_accesses == 0.0) && (tex_accesses != 0.0)){ - /* INT_FP_TEX */ - base_static_power = p->sys.static_cat5_flane; - lane_static_power = p->sys.static_cat5_addlane; - } + else if ((int_accesses != 0.0) && (fp_accesses != 0.0) && + (dp_accesses == 0.0) && (sfu_accesses == 0.0) && + (tensor_accesses == 0.0) && (tex_accesses != 0.0)) { + /* INT_FP_TEX */ + base_static_power = p->sys.static_cat5_flane; + lane_static_power = p->sys.static_cat5_addlane; + } - else if((int_accesses != 0.0) && (fp_accesses != 0.0) && (dp_accesses == 0.0) && (sfu_accesses == 0.0) && (tensor_accesses == 0.0) && (tex_accesses == 0.0)){ - /* INT_FP */ - base_static_power = p->sys.static_cat2_flane; - lane_static_power = p->sys.static_cat2_addlane; - } + else if ((int_accesses != 0.0) && (fp_accesses != 0.0) && + (dp_accesses == 0.0) && (sfu_accesses == 0.0) && + (tensor_accesses == 0.0) && (tex_accesses == 0.0)) { + /* INT_FP */ + base_static_power = p->sys.static_cat2_flane; + lane_static_power = p->sys.static_cat2_addlane; + } - else if((int_accesses != 0.0) && (fp_accesses == 0.0) && (dp_accesses == 0.0) && (sfu_accesses == 0.0) && (tensor_accesses == 0.0) && (tex_accesses == 0.0)){ - /* INT */ - /* Seperating INT_ADD only and INT_MUL only from mix of INT instructions */ - if((int_add_accesses != 0.0) && (int_mul_accesses == 0.0)){ //INT_ADD - base_static_power = p->sys.static_intadd_flane; - lane_static_power = p->sys.static_intadd_addlane; - } - else if((int_add_accesses == 0.0) && (int_mul_accesses != 0.0)){ //INT_MUL - base_static_power = p->sys.static_intmul_flane; - lane_static_power = p->sys.static_intmul_addlane; - } - else{ //INT_ADD+MUL - base_static_power = p->sys.static_cat1_flane; - lane_static_power = p->sys.static_cat1_addlane; - } - } + else if ((int_accesses != 0.0) && (fp_accesses == 0.0) && + (dp_accesses == 0.0) && (sfu_accesses == 0.0) && + (tensor_accesses == 0.0) && (tex_accesses == 0.0)) { + /* INT */ + /* Seperating INT_ADD only and INT_MUL only from mix of INT instructions */ + if ((int_add_accesses != 0.0) && (int_mul_accesses == 0.0)) { // INT_ADD + base_static_power = p->sys.static_intadd_flane; + lane_static_power = p->sys.static_intadd_addlane; + } else if ((int_add_accesses == 0.0) && + (int_mul_accesses != 0.0)) { // INT_MUL + base_static_power = p->sys.static_intmul_flane; + lane_static_power = p->sys.static_intmul_addlane; + } else { // INT_ADD+MUL + base_static_power = p->sys.static_cat1_flane; + lane_static_power = p->sys.static_cat1_addlane; + } + } - else if((int_accesses == 0.0) && (fp_accesses == 0.0) && (dp_accesses == 0.0) && (sfu_accesses == 0.0) && (tensor_accesses == 0.0) && (tex_accesses == 0.0)){ - /* LIGHT_SM or memory only sample */ - lane_static_power = 0.0; //addlane static power is 0 for l1/l2/shared memory only accesses - if(l1_accesses != 0.0) - base_static_power = p->sys.static_l1_flane; - else if(shared_accesses != 0.0) - base_static_power = p->sys.static_shared_flane; - else if(l2_accesses != 0.0) - base_static_power = p->sys.static_l2_flane; - else{ - base_static_power = p->sys.static_light_flane; - lane_static_power = p->sys.static_light_addlane; - } - } - else{ - base_static_power = p->sys.static_geomean_flane; //GEOMEAN except LIGHT_SM if we don't fall into any of the categories above - lane_static_power = p->sys.static_geomean_addlane; - } + else if ((int_accesses == 0.0) && (fp_accesses == 0.0) && + (dp_accesses == 0.0) && (sfu_accesses == 0.0) && + (tensor_accesses == 0.0) && (tex_accesses == 0.0)) { + /* LIGHT_SM or memory only sample */ + lane_static_power = + 0.0; // addlane static power is 0 for l1/l2/shared memory only accesses + if (l1_accesses != 0.0) + base_static_power = p->sys.static_l1_flane; + else if (shared_accesses != 0.0) + base_static_power = p->sys.static_shared_flane; + else if (l2_accesses != 0.0) + base_static_power = p->sys.static_l2_flane; + else { + base_static_power = p->sys.static_light_flane; + lane_static_power = p->sys.static_light_addlane; + } + } else { + base_static_power = + p->sys.static_geomean_flane; // GEOMEAN except LIGHT_SM if we don't + // fall into any of the categories above + lane_static_power = p->sys.static_geomean_addlane; + } - total_static_power = base_static_power + (((double)avg_threads_per_warp-1.0)*lane_static_power); //Linear Model - return (total_static_power*per_active_core); + total_static_power = + base_static_power + (((double)avg_threads_per_warp - 1.0) * + lane_static_power); // Linear Model + return (total_static_power * per_active_core); } -void gpgpu_sim_wrapper::update_components_power() -{ - +void gpgpu_sim_wrapper::update_components_power() { update_coefficients(); - proc_power=proc->rt_power.readOp.dynamic; - sample_cmp_pwr[IBP]=(proc->cores[0]->ifu->IB->rt_power.readOp.dynamic - +proc->cores[0]->ifu->IB->rt_power.writeOp.dynamic - +proc->cores[0]->ifu->ID_misc->rt_power.readOp.dynamic - +proc->cores[0]->ifu->ID_operand->rt_power.readOp.dynamic - +proc->cores[0]->ifu->ID_inst->rt_power.readOp.dynamic)/(proc->cores[0]->executionTime); + proc_power = proc->rt_power.readOp.dynamic; + sample_cmp_pwr[IBP] = + (proc->cores[0]->ifu->IB->rt_power.readOp.dynamic + + proc->cores[0]->ifu->IB->rt_power.writeOp.dynamic + + proc->cores[0]->ifu->ID_misc->rt_power.readOp.dynamic + + proc->cores[0]->ifu->ID_operand->rt_power.readOp.dynamic + + proc->cores[0]->ifu->ID_inst->rt_power.readOp.dynamic) / + (proc->cores[0]->executionTime); - sample_cmp_pwr[ICP]=proc->cores[0]->ifu->icache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[ICP] = proc->cores[0]->ifu->icache.rt_power.readOp.dynamic / + (proc->cores[0]->executionTime); - sample_cmp_pwr[DCP]=proc->cores[0]->lsu->dcache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[DCP] = proc->cores[0]->lsu->dcache.rt_power.readOp.dynamic / + (proc->cores[0]->executionTime); - sample_cmp_pwr[TCP]=proc->cores[0]->lsu->tcache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[TCP] = proc->cores[0]->lsu->tcache.rt_power.readOp.dynamic / + (proc->cores[0]->executionTime); - sample_cmp_pwr[CCP]=proc->cores[0]->lsu->ccache.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[CCP] = proc->cores[0]->lsu->ccache.rt_power.readOp.dynamic / + (proc->cores[0]->executionTime); - sample_cmp_pwr[SHRDP]=proc->cores[0]->lsu->sharedmemory.rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[SHRDP] = + proc->cores[0]->lsu->sharedmemory.rt_power.readOp.dynamic / + (proc->cores[0]->executionTime); - sample_cmp_pwr[RFP]=(proc->cores[0]->exu->rfu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)) - *(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); + sample_cmp_pwr[RFP] = + (proc->cores[0]->exu->rfu->rt_power.readOp.dynamic / + (proc->cores[0]->executionTime)) * + (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); - double sample_fp_pwr = (proc->cores[0]->exu->fp_u->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)); + double sample_fp_pwr = (proc->cores[0]->exu->fp_u->rt_power.readOp.dynamic / + (proc->cores[0]->executionTime)); - double sample_sfu_pwr = (proc->cores[0]->exu->mul->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)); + double sample_sfu_pwr = (proc->cores[0]->exu->mul->rt_power.readOp.dynamic / + (proc->cores[0]->executionTime)); - sample_cmp_pwr[INTP]=(proc->cores[0]->exu->exeu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime)) - *(proc->cores[0]->exu->rf_fu_clockRate/proc->cores[0]->exu->clockRate); + sample_cmp_pwr[INTP] = + (proc->cores[0]->exu->exeu->rt_power.readOp.dynamic / + (proc->cores[0]->executionTime)) * + (proc->cores[0]->exu->rf_fu_clockRate / proc->cores[0]->exu->clockRate); - - if(tot_fpu_accesses != 0){ - sample_cmp_pwr[FPUP]= sample_fp_pwr * sample_perf_counters[FP_ACC]/tot_fpu_accesses; - sample_cmp_pwr[DPUP]= sample_fp_pwr * sample_perf_counters[DP_ACC]/tot_fpu_accesses; - } - else{ - sample_cmp_pwr[FPUP]= 0; - sample_cmp_pwr[DPUP]= 0; - } - if(tot_sfu_accesses != 0){ - sample_cmp_pwr[INT_MUL24P]= sample_sfu_pwr * sample_perf_counters[INT_MUL24_ACC]/tot_sfu_accesses; - sample_cmp_pwr[INT_MUL32P]= sample_sfu_pwr * sample_perf_counters[INT_MUL32_ACC]/tot_sfu_accesses; - sample_cmp_pwr[INT_MULP]= sample_sfu_pwr * sample_perf_counters[INT_MUL_ACC]/tot_sfu_accesses; - sample_cmp_pwr[INT_DIVP]= sample_sfu_pwr * sample_perf_counters[INT_DIV_ACC]/tot_sfu_accesses; - sample_cmp_pwr[FP_MULP]= sample_sfu_pwr * sample_perf_counters[FP_MUL_ACC]/tot_sfu_accesses; - sample_cmp_pwr[FP_DIVP]= sample_sfu_pwr * sample_perf_counters[FP_DIV_ACC]/tot_sfu_accesses; - sample_cmp_pwr[FP_SQRTP]= sample_sfu_pwr * sample_perf_counters[FP_SQRT_ACC]/tot_sfu_accesses; - sample_cmp_pwr[FP_LGP]= sample_sfu_pwr * sample_perf_counters[FP_LG_ACC]/tot_sfu_accesses; - sample_cmp_pwr[FP_SINP]= sample_sfu_pwr * sample_perf_counters[FP_SIN_ACC]/tot_sfu_accesses; - sample_cmp_pwr[FP_EXP]= sample_sfu_pwr * sample_perf_counters[FP_EXP_ACC]/tot_sfu_accesses; - sample_cmp_pwr[DP_MULP]= sample_sfu_pwr * sample_perf_counters[DP_MUL_ACC]/tot_sfu_accesses; - sample_cmp_pwr[DP_DIVP]= sample_sfu_pwr * sample_perf_counters[DP_DIV_ACC]/tot_sfu_accesses; - sample_cmp_pwr[TENSORP]= sample_sfu_pwr * sample_perf_counters[TENSOR_ACC]/tot_sfu_accesses; - sample_cmp_pwr[TEXP]= sample_sfu_pwr * sample_perf_counters[TEX_ACC]/tot_sfu_accesses; + if (tot_fpu_accesses != 0) { + sample_cmp_pwr[FPUP] = + sample_fp_pwr * sample_perf_counters[FP_ACC] / tot_fpu_accesses; + sample_cmp_pwr[DPUP] = + sample_fp_pwr * sample_perf_counters[DP_ACC] / tot_fpu_accesses; + } else { + sample_cmp_pwr[FPUP] = 0; + sample_cmp_pwr[DPUP] = 0; } - else{ - sample_cmp_pwr[INT_MUL24P]= 0; - sample_cmp_pwr[INT_MUL32P]= 0; - sample_cmp_pwr[INT_MULP]= 0; - sample_cmp_pwr[INT_DIVP]= 0; - sample_cmp_pwr[FP_MULP]= 0; - sample_cmp_pwr[FP_DIVP]= 0; - sample_cmp_pwr[FP_SQRTP]= 0; - sample_cmp_pwr[FP_LGP]= 0; - sample_cmp_pwr[FP_SINP]= 0; - sample_cmp_pwr[FP_EXP]= 0; - sample_cmp_pwr[DP_MULP]= 0; - sample_cmp_pwr[DP_DIVP]= 0; - sample_cmp_pwr[TENSORP]= 0; - sample_cmp_pwr[TEXP]= 0; + if (tot_sfu_accesses != 0) { + sample_cmp_pwr[INT_MUL24P] = + sample_sfu_pwr * sample_perf_counters[INT_MUL24_ACC] / tot_sfu_accesses; + sample_cmp_pwr[INT_MUL32P] = + sample_sfu_pwr * sample_perf_counters[INT_MUL32_ACC] / tot_sfu_accesses; + sample_cmp_pwr[INT_MULP] = + sample_sfu_pwr * sample_perf_counters[INT_MUL_ACC] / tot_sfu_accesses; + sample_cmp_pwr[INT_DIVP] = + sample_sfu_pwr * sample_perf_counters[INT_DIV_ACC] / tot_sfu_accesses; + sample_cmp_pwr[FP_MULP] = + sample_sfu_pwr * sample_perf_counters[FP_MUL_ACC] / tot_sfu_accesses; + sample_cmp_pwr[FP_DIVP] = + sample_sfu_pwr * sample_perf_counters[FP_DIV_ACC] / tot_sfu_accesses; + sample_cmp_pwr[FP_SQRTP] = + sample_sfu_pwr * sample_perf_counters[FP_SQRT_ACC] / tot_sfu_accesses; + sample_cmp_pwr[FP_LGP] = + sample_sfu_pwr * sample_perf_counters[FP_LG_ACC] / tot_sfu_accesses; + sample_cmp_pwr[FP_SINP] = + sample_sfu_pwr * sample_perf_counters[FP_SIN_ACC] / tot_sfu_accesses; + sample_cmp_pwr[FP_EXP] = + sample_sfu_pwr * sample_perf_counters[FP_EXP_ACC] / tot_sfu_accesses; + sample_cmp_pwr[DP_MULP] = + sample_sfu_pwr * sample_perf_counters[DP_MUL_ACC] / tot_sfu_accesses; + sample_cmp_pwr[DP_DIVP] = + sample_sfu_pwr * sample_perf_counters[DP_DIV_ACC] / tot_sfu_accesses; + sample_cmp_pwr[TENSORP] = + sample_sfu_pwr * sample_perf_counters[TENSOR_ACC] / tot_sfu_accesses; + sample_cmp_pwr[TEXP] = + sample_sfu_pwr * sample_perf_counters[TEX_ACC] / tot_sfu_accesses; + } else { + sample_cmp_pwr[INT_MUL24P] = 0; + sample_cmp_pwr[INT_MUL32P] = 0; + sample_cmp_pwr[INT_MULP] = 0; + sample_cmp_pwr[INT_DIVP] = 0; + sample_cmp_pwr[FP_MULP] = 0; + sample_cmp_pwr[FP_DIVP] = 0; + sample_cmp_pwr[FP_SQRTP] = 0; + sample_cmp_pwr[FP_LGP] = 0; + sample_cmp_pwr[FP_SINP] = 0; + sample_cmp_pwr[FP_EXP] = 0; + sample_cmp_pwr[DP_MULP] = 0; + sample_cmp_pwr[DP_DIVP] = 0; + sample_cmp_pwr[TENSORP] = 0; + sample_cmp_pwr[TEXP] = 0; } - sample_cmp_pwr[SCHEDP]=proc->cores[0]->exu->scheu->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[SCHEDP] = proc->cores[0]->exu->scheu->rt_power.readOp.dynamic / + (proc->cores[0]->executionTime); - sample_cmp_pwr[L2CP]=(proc->XML->sys.number_of_L2s>0)? proc->l2array[0]->rt_power.readOp.dynamic/(proc->cores[0]->executionTime):0; + sample_cmp_pwr[L2CP] = (proc->XML->sys.number_of_L2s > 0) + ? proc->l2array[0]->rt_power.readOp.dynamic / + (proc->cores[0]->executionTime) + : 0; - sample_cmp_pwr[MCP]=(proc->mc->rt_power.readOp.dynamic-proc->mc->dram->rt_power.readOp.dynamic)/(proc->cores[0]->executionTime); + sample_cmp_pwr[MCP] = (proc->mc->rt_power.readOp.dynamic - + proc->mc->dram->rt_power.readOp.dynamic) / + (proc->cores[0]->executionTime); - sample_cmp_pwr[NOCP]=proc->nocs[0]->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[NOCP] = + proc->nocs[0]->rt_power.readOp.dynamic / (proc->cores[0]->executionTime); - sample_cmp_pwr[DRAMP]=proc->mc->dram->rt_power.readOp.dynamic/(proc->cores[0]->executionTime); + sample_cmp_pwr[DRAMP] = + proc->mc->dram->rt_power.readOp.dynamic / (proc->cores[0]->executionTime); - sample_cmp_pwr[PIPEP]=proc->cores[0]->Pipeline_energy/(proc->cores[0]->executionTime); + sample_cmp_pwr[PIPEP] = + proc->cores[0]->Pipeline_energy / (proc->cores[0]->executionTime); - sample_cmp_pwr[IDLE_COREP]=proc->cores[0]->IdleCoreEnergy/(proc->cores[0]->executionTime); + sample_cmp_pwr[IDLE_COREP] = + proc->cores[0]->IdleCoreEnergy / (proc->cores[0]->executionTime); - // This constant dynamic power (e.g., clock power) part is estimated via regression model. - sample_cmp_pwr[CONSTP]=0; - sample_cmp_pwr[STATICP]=0; - // double cnst_dyn = proc->get_const_dynamic_power()/(proc->cores[0]->executionTime); - // // If the regression scaling term is greater than the recorded constant dynamic power - // // then use the difference (other portion already added to dynamic power). Else, + // This constant dynamic power (e.g., clock power) part is estimated via + // regression model. + sample_cmp_pwr[CONSTP] = 0; + sample_cmp_pwr[STATICP] = 0; + // double cnst_dyn = + // proc->get_const_dynamic_power()/(proc->cores[0]->executionTime); + // // If the regression scaling term is greater than the recorded constant + // dynamic power + // // then use the difference (other portion already added to dynamic power). + // Else, // // all the constant dynamic power is accounted for, add nothing. // if(p->sys.scaling_coefficients[constant_power] > cnst_dyn) - // sample_cmp_pwr[CONSTP] = (p->sys.scaling_coefficients[constant_power]-cnst_dyn); + // sample_cmp_pwr[CONSTP] = + // (p->sys.scaling_coefficients[constant_power]-cnst_dyn); sample_cmp_pwr[CONSTP] = p->sys.scaling_coefficients[constant_power]; sample_cmp_pwr[STATICP] = calculate_static_power(); - if(g_dvfs_enabled){ - double voltage_ratio = modeled_chip_voltage/p->sys.modeled_chip_voltage_ref; - sample_cmp_pwr[IDLE_COREP] *= voltage_ratio; // static power scaled by voltage_ratio - sample_cmp_pwr[STATICP] *= voltage_ratio; // static power scaled by voltage_ratio - for(unsigned i=0; i<num_pwr_cmps; i++){ - if((i != IDLE_COREP) && (i != STATICP)){ - sample_cmp_pwr[i] *= voltage_ratio*voltage_ratio; // dynamic power scaled by square of voltage_ratio - } - } + if (g_dvfs_enabled) { + double voltage_ratio = + modeled_chip_voltage / p->sys.modeled_chip_voltage_ref; + sample_cmp_pwr[IDLE_COREP] *= + voltage_ratio; // static power scaled by voltage_ratio + sample_cmp_pwr[STATICP] *= + voltage_ratio; // static power scaled by voltage_ratio + for (unsigned i = 0; i < num_pwr_cmps; i++) { + if ((i != IDLE_COREP) && (i != STATICP)) { + sample_cmp_pwr[i] *= + voltage_ratio * + voltage_ratio; // dynamic power scaled by square of voltage_ratio + } + } } - - proc_power+=sample_cmp_pwr[CONSTP]+sample_cmp_pwr[STATICP]; - if(!g_dvfs_enabled){ // sanity check will fail when voltage scaling is applied, fix later - double sum_pwr_cmp=0; - for(unsigned i=0; i<num_pwr_cmps; i++){ - sum_pwr_cmp+=sample_cmp_pwr[i]; - } - bool check=false; - check=sanity_check(sum_pwr_cmp,proc_power); - if(!check) - printf("sum_pwr_cmp %f : proc_power %f \n",sum_pwr_cmp,proc_power); - assert("Total Power does not equal the sum of the components\n" && (check)); + + proc_power += sample_cmp_pwr[CONSTP] + sample_cmp_pwr[STATICP]; + if (!g_dvfs_enabled) { // sanity check will fail when voltage scaling is + // applied, fix later + double sum_pwr_cmp = 0; + for (unsigned i = 0; i < num_pwr_cmps; i++) { + sum_pwr_cmp += sample_cmp_pwr[i]; + } + bool check = false; + check = sanity_check(sum_pwr_cmp, proc_power); + if (!check) + printf("sum_pwr_cmp %f : proc_power %f \n", sum_pwr_cmp, proc_power); + assert("Total Power does not equal the sum of the components\n" && (check)); } } @@ -993,13 +1111,12 @@ void gpgpu_sim_wrapper::print_power_kernel_stats( } powerfile << "gpu_avg_threads_per_warp = " - << avg_threads_per_warp_tot / (double)kernel_sample_count - << std::endl; + << avg_threads_per_warp_tot / (double)kernel_sample_count + << std::endl; for (unsigned i = 0; i < num_perf_counters; ++i) { powerfile << "gpu_tot_" << perf_count_label[i] << " = " - << kernel_cmp_perf_counters[i].avg - << std::endl; + << kernel_cmp_perf_counters[i].avg << std::endl; } powerfile << std::endl << "Kernel Maximum Power Data:" << std::endl; diff --git a/src/accelwattch/gpgpu_sim_wrapper.h b/src/accelwattch/gpgpu_sim_wrapper.h index 33c4b72..dd71d89 100644 --- a/src/accelwattch/gpgpu_sim_wrapper.h +++ b/src/accelwattch/gpgpu_sim_wrapper.h @@ -1,16 +1,17 @@ -// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington, Ahmed ElTantawy, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington, Ahmed ElTantawy, +// Vijay Kandiah, Nikos Hardavellas The University of British Columbia, +// Northwestern University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -58,31 +59,32 @@ struct avg_max_min_counters { #ifndef COEFF_STRUCT #define COEFF_STRUCT -struct PowerscalingCoefficients{ - double int_coeff; - double int_mul_coeff; - double int_mul24_coeff; - double int_mul32_coeff; - double int_div_coeff; - double fp_coeff; - double dp_coeff; - double fp_mul_coeff; - double fp_div_coeff; - double dp_mul_coeff; - double dp_div_coeff; - double sqrt_coeff; - double log_coeff; - double sin_coeff; - double exp_coeff; - double tensor_coeff; - double tex_coeff; +struct PowerscalingCoefficients { + double int_coeff; + double int_mul_coeff; + double int_mul24_coeff; + double int_mul32_coeff; + double int_div_coeff; + double fp_coeff; + double dp_coeff; + double fp_mul_coeff; + double fp_div_coeff; + double dp_mul_coeff; + double dp_div_coeff; + double sqrt_coeff; + double log_coeff; + double sin_coeff; + double exp_coeff; + double tensor_coeff; + double tex_coeff; }; #endif class gpgpu_sim_wrapper { public: - gpgpu_sim_wrapper(bool power_simulation_enabled, char* xmlfile, int power_simulation_mode, bool dvfs_enabled); + gpgpu_sim_wrapper(bool power_simulation_enabled, char* xmlfile, + int power_simulation_mode, bool dvfs_enabled); ~gpgpu_sim_wrapper(); void init_mcpat(char* xmlfile, char* powerfile, char* power_trace_file, @@ -90,8 +92,9 @@ class gpgpu_sim_wrapper { bool power_sim_enabled, bool trace_enabled, bool steady_state_enabled, bool power_per_cycle_dump, double steady_power_deviation, double steady_min_period, - int zlevel, double init_val, int stat_sample_freq, int power_sim_mode, - bool dvfs_enabled, unsigned clock_freq, unsigned num_shaders); + int zlevel, double init_val, int stat_sample_freq, + int power_sim_mode, bool dvfs_enabled, unsigned clock_freq, + unsigned num_shaders); void init_mcpat_hw_mode(unsigned gpu_sim_cycle); void detect_print_steady_state(int position, double init_val); void close_files(); @@ -128,15 +131,15 @@ class gpgpu_sim_wrapper { void set_mem_ctrl_power(double reads, double writes, double dram_precharge); void set_exec_unit_power(double fpu_accesses, double ialu_accesses, double sfu_accesses); - void set_int_accesses(double ialu_accesses, double imul24_accesses, - double imul32_accesses, double imul_accesses, + void set_int_accesses(double ialu_accesses, double imul24_accesses, + double imul32_accesses, double imul_accesses, double idiv_accesses); - void set_dp_accesses(double dpu_accesses, double dpmul_accesses, + void set_dp_accesses(double dpu_accesses, double dpmul_accesses, double dpdiv_accesses); - void set_fp_accesses(double fpu_accesses, double fpmul_accesses, + void set_fp_accesses(double fpu_accesses, double fpmul_accesses, double fpdiv_accesses); - void set_trans_accesses(double sqrt_accesses, double log_accesses, - double sin_accesses, double exp_accesses); + void set_trans_accesses(double sqrt_accesses, double log_accesses, + double sin_accesses, double exp_accesses); void set_tensor_accesses(double tensor_accesses); void set_tex_accesses(double tex_accesses); void set_avg_active_threads(float active_threads); @@ -145,7 +148,7 @@ class gpgpu_sim_wrapper { void set_NoC_power(double noc_tot_acc); bool sanity_check(double a, double b); - PowerscalingCoefficients * get_scaling_coeffs(); + PowerscalingCoefficients* get_scaling_coeffs(); private: void print_steady_state(int position, double init_val); diff --git a/src/accelwattch/processor.cc b/src/accelwattch/processor.cc index 9e7f5b2..d5c7cdd 100644 --- a/src/accelwattch/processor.cc +++ b/src/accelwattch/processor.cc @@ -30,8 +30,8 @@ ***************************************************************************/ /******************************************************************** * Modified by: - * Jingwen Leng, University of Texas, Austin - * Syed Gilani, University of Wisconsin–Madison + * Jingwen Leng, University of Texas, Austin + * Syed Gilani, University of Wisconsin–Madison * Tayler Hetherington, University of British Columbia * Ahmed ElTantawy, University of British Columbia * Vijay Kandiah, Northwestern University diff --git a/src/accelwattch/xmlParser.cc b/src/accelwattch/xmlParser.cc index 8f49b39..780d2ad 100644 --- a/src/accelwattch/xmlParser.cc +++ b/src/accelwattch/xmlParser.cc @@ -1236,12 +1236,10 @@ static NextToken GetNextToken(XML *pXML, int *pcbToken, // Indicate we are dealing with text *pType = eTokenText; while ((ch = getNextChar(pXML))) { - if - XML_isSPACECHAR(ch) { - indexStart++; - break; - } - else if (ch == _CXML('/')) { + if XML_isSPACECHAR (ch) { + indexStart++; + break; + } else if (ch == _CXML('/')) { // If we find a slash then this maybe text or a short hand end tag // Peek at the next character to see it we have short hand end tag ch = pXML->lpXML[pXML->nIndex]; @@ -2193,15 +2191,15 @@ int XMLNode::CreateXMLStringR(XMLNodeData *pEntry, XMLSTR lpszMarker, nResult++; } } else - // If there are child nodes we need to terminate the start tag - if (nElementI) { - if (lpszMarker) lpszMarker[nResult - 1] = _CXML('>'); - if (nFormat >= 0) { - if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); - nResult++; - } - } else - nResult--; + // If there are child nodes we need to terminate the start tag + if (nElementI) { + if (lpszMarker) lpszMarker[nResult - 1] = _CXML('>'); + if (nFormat >= 0) { + if (lpszMarker) lpszMarker[nResult] = _CXML('\n'); + nResult++; + } + } else + nResult--; } // Calculate the child format for when we recurse. This is used to diff --git a/src/cuda-sim/CMakeLists.txt b/src/cuda-sim/CMakeLists.txt new file mode 100644 index 0000000..3378b77 --- /dev/null +++ b/src/cuda-sim/CMakeLists.txt @@ -0,0 +1,78 @@ +# Specify Flex and Bison target +BISON_TARGET(ptx_parser ptx.y ${CMAKE_CURRENT_BINARY_DIR}/ptx.tab.c + COMPILE_FLAGS "--name-prefix=ptx_ -v -d --file-prefix=${CMAKE_CURRENT_BINARY_DIR}/ptx") +BISON_TARGET(ptxinfo_parser ptxinfo.y ${CMAKE_CURRENT_BINARY_DIR}/ptxinfo.tab.c + COMPILE_FLAGS "--name-prefix=ptxinfo_ -v -d --file-prefix=${CMAKE_CURRENT_BINARY_DIR}/ptxinfo") +FLEX_TARGET(ptx_lexer ptx.l ${CMAKE_CURRENT_BINARY_DIR}/lex.ptx_.c) +FLEX_TARGET(ptxinfo_lexer ptxinfo.l ${CMAKE_CURRENT_BINARY_DIR}/lex.ptxinfo_.c) +ADD_FLEX_BISON_DEPENDENCY(ptx_lexer ptx_parser) +ADD_FLEX_BISON_DEPENDENCY(ptxinfo_lexer ptxinfo_parser) + +# The flex and bison are using CXX, need to set their generated files to CXX so that +# they can be compiled and linked +set_source_files_properties(${BISON_ptx_parser_OUTPUT_SOURCE} + ${FLEX_ptx_lexer_OUTPUTS} + ${BISON_ptxinfo_parser_OUTPUT_SOURCE} + ${FLEX_ptxinfo_lexer_OUTPUTS} + PROPERTIES LANGUAGE CXX) +# Create libptxsim.a +add_library(ptxsim STATIC + cuda_device_printf.cc + cuda_device_runtime.cc + cuda-sim.cc + instructions.cc + memory.cc + ptx_ir.cc + ptx_loader.cc + ptx_parser.cc + ptx_sim.cc + ptx-stats.cc + decuda_pred_table/decuda_pred_table.cc + ${BISON_ptx_parser_OUTPUT_SOURCE} ${FLEX_ptx_lexer_OUTPUTS} + ${BISON_ptxinfo_parser_OUTPUT_SOURCE} ${FLEX_ptxinfo_lexer_OUTPUTS}) + +# Define this for all source files, though we just need it for parser +target_compile_definitions(ptxsim PRIVATE YYDEBUG) +target_include_directories(ptxsim PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/decuda_pred_table) +target_include_directories(ptxsim PUBLIC ${CUDAToolkit_INCLUDE_DIRS}) +target_include_directories(ptxsim PRIVATE ${CMAKE_BINARY_DIR}) + +# ptxsim need buildstring +add_dependencies(ptxsim gen_build_string) + +# Create instructions.h using custom command +add_custom_target(gen_instructions_h DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/instructions.h) +add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/instructions.h + COMMAND touch ${CMAKE_CURRENT_BINARY_DIR}/instructions.h + COMMAND chmod +w ${CMAKE_CURRENT_BINARY_DIR}/instructions.h + COMMAND echo "// DO NOT EDIT THIS FILE! IT IS AUTOMATICALLY GENERATED BY THE MAKEFILE (see target for instructions.h)" > ${CMAKE_CURRENT_BINARY_DIR}/instructions.h + COMMAND echo "#include \"ptx_ir.h\"" >> ${CMAKE_CURRENT_BINARY_DIR}/instructions.h + COMMAND echo "#ifndef instructions_h_included" >> ${CMAKE_CURRENT_BINARY_DIR}/instructions.h + COMMAND echo "#define instructions_h_included" >> ${CMAKE_CURRENT_BINARY_DIR}/instructions.h + COMMAND cat ${CMAKE_CURRENT_SOURCE_DIR}/instructions.cc | grep "_impl(" | sed "s/{.*//" | sed "s/$/;/" >> ${CMAKE_CURRENT_BINARY_DIR}/instructions.h + COMMAND echo "#endif" >> ${CMAKE_CURRENT_BINARY_DIR}/instructions.h + # COMMAND chmod -w ${CMAKE_CURRENT_BINARY_DIR}/instructions.h + DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/instructions.cc + VERBATIM +) +add_dependencies(ptxsim gen_instructions_h) + +# Create ptx_parser_decode.def using custom command +add_custom_target(gen_ptx_parser_decode DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/ptx_parser_decode.def) +if(UNIX) + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ptx_parser_decode.def + COMMAND cat ${CMAKE_CURRENT_BINARY_DIR}/ptx.tab.h | grep "=" | sed "s/^[ ]\\+//" | sed -E "s/\\s+\\/\\*.+\\*\\///" | sed "s/[=,]//g" | sed "s/\\([_A-Z1-9]\\+\\)[ ]\\+\\([0-9]\\+\\)/\\1 \\1/" | sed "s/^/DEF(/" | sed "s/ /,\"/" | sed "s/$/\")/" | sed "/YYerror/d;/YYEOF/d;/YYEMPTY/d;/YYUNDEF/d;" > ${CMAKE_CURRENT_BINARY_DIR}/ptx_parser_decode.def + DEPENDS ${BISON_ptx_parser_OUTPUTS} + VERBATIM + ) +else() + add_custom_command( + OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/ptx_parser_decode.def + COMMAND cat ${CMAKE_CURRENT_BINARY_DIR}/ptx.tab.h | grep "=" | sed -E "s/^ +//" | sed -E "s/\\s+\\/\\*.+\\*\\///" | sed "s/[=,]//g" | sed -E "s/([_A-Z1-9]+).*/\\1 \\1/" | sed "s/^/DEF(/" | sed "s/ /,\"/" | sed "s/$/\")/" | sed "/YYerror/d;/YYEOF/d;/YYEMPTY/d;/YYUNDEF/d;" > ${CMAKE_CURRENT_BINARY_DIR}/ptx_parser_decode.def + DEPENDS ${BISON_ptx_parser_OUTPUTS} + VERBATIM + ) +endif() +add_dependencies(ptxsim gen_ptx_parser_decode) diff --git a/src/cuda-sim/Makefile b/src/cuda-sim/Makefile index 85d1c8c..541cf8f 100644 --- a/src/cuda-sim/Makefile +++ b/src/cuda-sim/Makefile @@ -91,16 +91,16 @@ $(OUTPUT_DIR)/lex.ptxinfo_.o: $(OUTPUT_DIR)/lex.ptxinfo_.c $(OUTPUT_DIR)/ptxinfo $(CPP) -c $(CXX_OPT) $(OUTPUT_DIR)/lex.ptxinfo_.c -o $(OUTPUT_DIR)/lex.ptxinfo_.o $(OUTPUT_DIR)/ptx.tab.c: ptx.y - bison --name-prefix=ptx_ -v -d ptx.y --file-prefix=$(OUTPUT_DIR)/ptx + bison --name-prefix=ptx_ -v -d ptx.y --file-prefix=$(OUTPUT_DIR)/ptx 2> /dev/null $(OUTPUT_DIR)/ptxinfo.tab.c: ptxinfo.y - bison --name-prefix=ptxinfo_ -v -d ptxinfo.y --file-prefix=$(OUTPUT_DIR)/ptxinfo + bison --name-prefix=ptxinfo_ -v -d ptxinfo.y --file-prefix=$(OUTPUT_DIR)/ptxinfo 2> /dev/null $(OUTPUT_DIR)/lex.ptx_.c: ptx.l - flex --outfile=$(OUTPUT_DIR)/lex.ptx_.c ptx.l + flex --outfile=$(OUTPUT_DIR)/lex.ptx_.c ptx.l 2> /dev/null $(OUTPUT_DIR)/lex.ptxinfo_.c: ptxinfo.l - flex --outfile=$(OUTPUT_DIR)/lex.ptxinfo_.c ptxinfo.l + flex --outfile=$(OUTPUT_DIR)/lex.ptxinfo_.c ptxinfo.l 2> /dev/null clean: rm -f *~ *.o *.gcda *.gcno *.gcov libgpgpu_ptx_sim.a \ @@ -129,9 +129,9 @@ $(OUTPUT_DIR)/instructions.h: instructions.cc $(OUTPUT_DIR)/ptx_parser_decode.def: $(OUTPUT_DIR)/ptx.tab.c ifeq ($(shell uname),Linux) - cat $(OUTPUT_DIR)/ptx.tab.h | grep "=" | sed 's/^[ ]\+//' | sed 's/[=,]//g' | sed 's/\([_A-Z1-9]\+\)[ ]\+\([0-9]\+\)/\1 \1/' | sed 's/^/DEF(/' | sed 's/ /,"/' | sed 's/$$/")/' > $(OUTPUT_DIR)/ptx_parser_decode.def + cat $(OUTPUT_DIR)/ptx.tab.h | grep "=" | sed 's/^[ ]\+//' | sed -E 's/\s+\/\*.+\*\///' | sed 's/[=,]//g' | sed 's/\([_A-Z1-9]\+\)[ ]\+\([0-9]\+\)/\1 \1/' | sed 's/^/DEF(/' | sed 's/ /,"/' | sed 's/$$/")/' | sed '/YYerror/d;/YYEOF/d;/YYEMPTY/d;/YYUNDEF/d;'> $(OUTPUT_DIR)/ptx_parser_decode.def else - cat $(OUTPUT_DIR)/ptx.tab.h | grep "=" | sed -E 's/^ +//' | sed 's/[=,]//g' | sed -E 's/([_A-Z1-9]+).*/\1 \1/' | sed 's/^/DEF(/' | sed 's/ /,"/' | sed 's/$$/")/' > $(OUTPUT_DIR)/ptx_parser_decode.def + cat $(OUTPUT_DIR)/ptx.tab.h | grep "=" | sed -E 's/^ +//' | sed -E 's/\s+\/\*.+\*\///' | sed 's/[=,]//g' | sed -E 's/([_A-Z1-9]+).*/\1 \1/' | sed 's/^/DEF(/' | sed 's/ /,"/' | sed 's/$$/")/' | sed '/YYerror/d;/YYEOF/d;/YYEMPTY/d;/YYUNDEF/d;' > $(OUTPUT_DIR)/ptx_parser_decode.def endif $(OUTPUT_DIR)/instructions.o: $(OUTPUT_DIR)/instructions.h $(OUTPUT_DIR)/ptx.tab.c diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc index f9e5db3..2fd90c0 100644 --- a/src/cuda-sim/cuda-sim.cc +++ b/src/cuda-sim/cuda-sim.cc @@ -1,17 +1,19 @@ // Copyright (c) 2009-2021, Tor M. Aamodt, Ali Bakhoda, Wilson W.L. Fung, -// George L. Yuan, Jimmy Kwa, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// George L. Yuan, Jimmy Kwa, Vijay Kandiah, Nikos Hardavellas, +// Mahmoud Khairy, Junrui Pan, Timothy G. Rogers +// The University of British Columbia, Northwestern University, Purdue +// University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -544,7 +546,7 @@ void gpgpu_t::gpu_memset(size_t dst_start_addr, int c, size_t count) { void cuda_sim::ptx_print_insn(address_type pc, FILE *fp) { std::map<unsigned, function_info *>::iterator f = g_pc_to_finfo.find(pc); if (f == g_pc_to_finfo.end()) { - fprintf(fp, "<no instruction at address 0x%x>", pc); + fprintf(fp, "<no instruction at address 0x%llx>", pc); return; } function_info *finfo = f->second; @@ -558,7 +560,7 @@ std::string cuda_sim::ptx_get_insn_str(address_type pc) { #define STR_SIZE 255 char buff[STR_SIZE]; buff[STR_SIZE - 1] = '\0'; - snprintf(buff, STR_SIZE, "<no instruction at address 0x%x>", pc); + snprintf(buff, STR_SIZE, "<no instruction at address 0x%llx>", pc); return std::string(buff); } function_info *finfo = f->second; @@ -590,118 +592,118 @@ void ptx_instruction::set_fp_or_int_archop() { } } -void ptx_instruction::set_mul_div_or_other_archop(){ - sp_op=OTHER_OP; - if((m_opcode != MEMBAR_OP) && (m_opcode != SSY_OP) && (m_opcode != BRA_OP) && (m_opcode != BAR_OP) && (m_opcode != EXIT_OP) && (m_opcode != NOP_OP) && (m_opcode != RETP_OP) && (m_opcode != RET_OP) && (m_opcode != CALLP_OP) && (m_opcode != CALL_OP)){ - if(get_type() == F64_TYPE || get_type() == FF64_TYPE){ - switch(get_opcode()){ - case MUL_OP: - case MAD_OP: - case FMA_OP: - sp_op=DP_MUL_OP; - break; - case DIV_OP: - case REM_OP: - sp_op=DP_DIV_OP; - break; - case RCP_OP: - sp_op=DP_DIV_OP; - break; - case LG2_OP: - sp_op=FP_LG_OP; - break; - case RSQRT_OP: - case SQRT_OP: - sp_op=FP_SQRT_OP; - break; - case SIN_OP: - case COS_OP: - sp_op=FP_SIN_OP; - break; - case EX2_OP: - sp_op=FP_EXP_OP; - break; - case MMA_OP: - sp_op=TENSOR__OP; - break; - case TEX_OP: - sp_op=TEX__OP; - break; - default: - if((op==DP_OP) || (op==ALU_OP)) - sp_op=DP___OP; - break; - } +void ptx_instruction::set_mul_div_or_other_archop() { + sp_op = OTHER_OP; + if ((m_opcode != MEMBAR_OP) && (m_opcode != SSY_OP) && (m_opcode != BRA_OP) && + (m_opcode != BAR_OP) && (m_opcode != EXIT_OP) && (m_opcode != NOP_OP) && + (m_opcode != RETP_OP) && (m_opcode != RET_OP) && (m_opcode != CALLP_OP) && + (m_opcode != CALL_OP)) { + if (get_type() == F64_TYPE || get_type() == FF64_TYPE) { + switch (get_opcode()) { + case MUL_OP: + case MAD_OP: + case FMA_OP: + sp_op = DP_MUL_OP; + break; + case DIV_OP: + case REM_OP: + sp_op = DP_DIV_OP; + break; + case RCP_OP: + sp_op = DP_DIV_OP; + break; + case LG2_OP: + sp_op = FP_LG_OP; + break; + case RSQRT_OP: + case SQRT_OP: + sp_op = FP_SQRT_OP; + break; + case SIN_OP: + case COS_OP: + sp_op = FP_SIN_OP; + break; + case EX2_OP: + sp_op = FP_EXP_OP; + break; + case MMA_OP: + sp_op = TENSOR__OP; + break; + case TEX_OP: + sp_op = TEX__OP; + break; + default: + if ((op == DP_OP) || (op == ALU_OP)) sp_op = DP___OP; + break; } - else if(get_type()==F16_TYPE || get_type()==F32_TYPE){ - switch(get_opcode()){ - case MUL_OP: - case MAD_OP: - case FMA_OP: - sp_op=FP_MUL_OP; - break; - case DIV_OP: - case REM_OP: - sp_op=FP_DIV_OP; - break; - case RCP_OP: - sp_op=FP_DIV_OP; - break; - case LG2_OP: - sp_op=FP_LG_OP; - break; - case RSQRT_OP: - case SQRT_OP: - sp_op=FP_SQRT_OP; - break; - case SIN_OP: - case COS_OP: - sp_op=FP_SIN_OP; - break; - case EX2_OP: - sp_op=FP_EXP_OP; - break; - case MMA_OP: - sp_op=TENSOR__OP; - break; - case TEX_OP: - sp_op=TEX__OP; - break; - default: - if((op==SP_OP) || (op==ALU_OP)) - sp_op=FP__OP; - break; - } - }else { - switch(get_opcode()){ - case MUL24_OP: - case MAD24_OP: - sp_op=INT_MUL24_OP; - break; - case MUL_OP: - case MAD_OP: - case FMA_OP: - if(get_type()==U32_TYPE || get_type()==S32_TYPE || get_type()==B32_TYPE) - sp_op=INT_MUL32_OP; - else - sp_op=INT_MUL_OP; - break; - case DIV_OP: - case REM_OP: - sp_op=INT_DIV_OP; - break; - case MMA_OP: - sp_op=TENSOR__OP; - break; - case TEX_OP: - sp_op=TEX__OP; - break; - default: - if((op==INTP_OP) || (op==ALU_OP)) - sp_op=INT__OP; - break; - } + } else if (get_type() == F16_TYPE || get_type() == F32_TYPE) { + switch (get_opcode()) { + case MUL_OP: + case MAD_OP: + case FMA_OP: + sp_op = FP_MUL_OP; + break; + case DIV_OP: + case REM_OP: + sp_op = FP_DIV_OP; + break; + case RCP_OP: + sp_op = FP_DIV_OP; + break; + case LG2_OP: + sp_op = FP_LG_OP; + break; + case RSQRT_OP: + case SQRT_OP: + sp_op = FP_SQRT_OP; + break; + case SIN_OP: + case COS_OP: + sp_op = FP_SIN_OP; + break; + case EX2_OP: + sp_op = FP_EXP_OP; + break; + case MMA_OP: + sp_op = TENSOR__OP; + break; + case TEX_OP: + sp_op = TEX__OP; + break; + default: + if ((op == SP_OP) || (op == ALU_OP)) sp_op = FP__OP; + break; + } + } else { + switch (get_opcode()) { + case MUL24_OP: + case MAD24_OP: + sp_op = INT_MUL24_OP; + break; + case MUL_OP: + case MAD_OP: + case FMA_OP: + if (get_type() == U32_TYPE || get_type() == S32_TYPE || + get_type() == B32_TYPE) + sp_op = INT_MUL32_OP; + else + sp_op = INT_MUL_OP; + break; + case DIV_OP: + case REM_OP: + sp_op = INT_DIV_OP; + break; + case MMA_OP: + sp_op = TENSOR__OP; + break; + case TEX_OP: + sp_op = TEX__OP; + break; + default: + if ((op == INTP_OP) || (op == ALU_OP)) sp_op = INT__OP; + break; } + } } } @@ -959,14 +961,16 @@ void ptx_instruction::set_opcode_and_latency() { break; } break; - case MUL24_OP: //MUL24 is performed on mul32 units (with additional instructions for bitmasking) on devices with compute capability >1.x - latency = int_latency[2]+1; - initiation_interval = int_init[2]+1; + case MUL24_OP: // MUL24 is performed on mul32 units (with additional + // instructions for bitmasking) on devices with compute + // capability >1.x + latency = int_latency[2] + 1; + initiation_interval = int_init[2] + 1; op = INTP_OP; break; case MAD24_OP: - latency = int_latency[3]+1; - initiation_interval = int_init[3]+1; + latency = int_latency[3] + 1; + initiation_interval = int_init[3] + 1; op = INTP_OP; break; case DIV_OP: @@ -1301,7 +1305,12 @@ void function_info::add_param_name_type_size(unsigned index, std::string name, void function_info::add_param_data(unsigned argn, struct gpgpu_ptx_sim_arg *args) { const void *data = args->m_start; - + if (g_debug_execution >= 3) { + if (args->m_nbytes == 4) + printf("ADD_PARAM_DATA %d\n", *((uint32_t *)data)); + else + printf("ADD_PARAM_DATA %p\n", *((void **)data)); + } bool scratchpad_memory_param = false; // Is this parameter in CUDA shared memory or OpenCL local memory @@ -1371,7 +1380,7 @@ void function_info::add_param_data(unsigned argn, unsigned num_bits = 8 * args->m_nbytes; printf( "GPGPU-Sim PTX: deferred allocation of shared region for \"%s\" from " - "0x%x to 0x%x (shared memory space)\n", + "0x%llx to 0x%llx (shared memory space)\n", p->name().c_str(), m_symtab->get_shared_next(), m_symtab->get_shared_next() + num_bits / 8); fflush(stdout); @@ -1502,7 +1511,7 @@ void function_info::list_param(FILE *fout) const { std::string name = p.get_name(); symbol *param = m_symtab->lookup(name.c_str()); addr_t param_addr = param->get_address(); - fprintf(fout, "%s: %#08x\n", name.c_str(), param_addr); + fprintf(fout, "%s: %#08llx\n", name.c_str(), param_addr); } fflush(fout); } @@ -1530,9 +1539,13 @@ void function_info::ptx_jit_config( std::string filename_c(filename + "_c"); snprintf(buff, 1024, "c++filt %s > %s", get_name().c_str(), filename_c.c_str()); - assert(system(buff) != NULL); + assert(system(buff) != 0); FILE *fp = fopen(filename_c.c_str(), "r"); - fgets(buff, 1024, fp); + char *ptr = fgets(buff, 1024, fp); + if (ptr == NULL) { + printf("can't read file %s \n", filename_c.c_str()); + assert(0); + } fclose(fp); std::string fn(buff); size_t pos1, pos2; @@ -1738,6 +1751,17 @@ static unsigned get_tex_datasize(const ptx_instruction *pI, ptx_thread_info *thread) { const operand_info &src1 = pI->src1(); // the name of the texture std::string texname = src1.name(); + // If indirect access, use register's value as address + // to find the symbol + if (src1.is_reg()) { + const operand_info &dst = pI->dst(); + ptx_reg_t src1_data = + thread->get_operand_value(src1, dst, pI->get_type(), thread, 1); + addr_t sym_addr = src1_data.u64; + symbol *texRef = thread->get_symbol_table()->lookup_by_addr(sym_addr); + assert(texRef != NULL); + texname = texRef->name(); + } /* For programs with many streams, textures can be bound and unbound @@ -1876,7 +1900,7 @@ void ptx_thread_info::ptx_exec_inst(warp_inst_t &inst, unsigned lane_id) { dim3 tid = get_tid(); printf( "%u [thd=%u][i=%u] : ctaid=(%u,%u,%u) tid=(%u,%u,%u) icount=%u " - "[pc=%u] (%s:%u - %s) [0x%llx]\n", + "[pc=%llu] (%s:%u - %s) [0x%llx]\n", m_gpu->gpgpu_ctx->func_sim->g_ptx_sim_num_insn, get_uid(), pI->uid(), ctaid.x, ctaid.y, ctaid.z, tid.x, tid.y, tid.z, get_icount(), pc, pI->source_file(), pI->source_line(), pI->get_source(), @@ -2277,15 +2301,24 @@ void cuda_sim::gpgpu_ptx_sim_memcpy_symbol(const char *hostVar, const void *src, sym_name = g->second; mem_region = global_space; } - if (g_globals.find(hostVar) != g_globals.end()) { - found_sym = true; - sym_name = hostVar; - mem_region = global_space; - } - if (g_constants.find(hostVar) != g_constants.end()) { - found_sym = true; - sym_name = hostVar; - mem_region = const_space; + + // Weili: Only attempt to find symbol as it is a string + // if we could not find it in previously registered variable. + // This will avoid constructing std::string() from hostVar address + // where it is not a string as + // Use of a string naming a variable as the symbol parameter was deprecated in + // CUDA 4.1 and removed in CUDA 5.0. + if (!found_sym) { + if (g_globals.find(hostVar) != g_globals.end()) { + found_sym = true; + sym_name = hostVar; + mem_region = global_space; + } + if (g_constants.find(hostVar) != g_constants.end()) { + found_sym = true; + sym_name = hostVar; + mem_region = const_space; + } } if (!found_sym) { @@ -2375,7 +2408,7 @@ void cuda_sim::read_sim_environment_variables() { "%s\n", dbg_pc); fflush(stdout); - sscanf(dbg_pc, "%d", &g_debug_pc); + sscanf(dbg_pc, "%llu", &g_debug_pc); } #if CUDART_VERSION > 1010 diff --git a/src/cuda-sim/cuda_device_runtime.cc b/src/cuda-sim/cuda_device_runtime.cc index 4a99c1c..8ed90bc 100644 --- a/src/cuda-sim/cuda_device_runtime.cc +++ b/src/cuda-sim/cuda_device_runtime.cc @@ -36,7 +36,7 @@ void cuda_device_runtime::gpgpusim_cuda_getParameterBufferV2( unsigned n_args = target_func->num_args(); assert(n_args == 4); - function_info *child_kernel_entry; + function_info *child_kernel_entry = NULL; struct dim3 grid_dim, block_dim; unsigned int shared_mem; @@ -258,7 +258,7 @@ void cuda_device_runtime::gpgpusim_cuda_streamCreateWithFlags( assert(n_args == 2); size_t generic_pStream_addr; - addr_t pStream_addr; + addr_t pStream_addr = 0; unsigned int flags; for (unsigned arg = 0; arg < n_args; arg++) { const operand_info &actual_param_op = diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc index 44afbe5..843bf0b 100644 --- a/src/cuda-sim/instructions.cc +++ b/src/cuda-sim/instructions.cc @@ -1,17 +1,19 @@ // Copyright (c) 2009-2021, Tor M. Aamodt, Wilson W.L. Fung, Ali Bakhoda, -// Jimmy Kwa, George L. Yuan, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// Jimmy Kwa, George L. Yuan, Vijay Kandiah, Nikos Hardavellas, +// Mahmoud Khairy, Junrui Pan, Timothy G. Rogers +// The University of British Columbia, Northwestern University, Purdue +// University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -1947,7 +1949,7 @@ void mma_impl(const ptx_instruction *pI, core_t *core, warp_inst_t inst) { hex_val = (v[k / 2].s64 & 0xffff); else hex_val = ((v[k / 2].s64 & 0xffff0000) >> 16); - nw_v[k].f16 = *((half *)&hex_val); + nw_v[k].f16 = *(reinterpret_cast<half *>(hex_val)); } } if (!((operand_num == 3) && (type2 == F32_TYPE))) { @@ -3979,7 +3981,7 @@ void mad_def(const ptx_instruction *pI, ptx_thread_info *thread, fesetround(FE_TOWARDZERO); break; default: - //assert(0); + // assert(0); break; } d.f32 = a.f32 * b.f32 + c.f32; @@ -4325,7 +4327,7 @@ void mul_impl(const ptx_instruction *pI, ptx_thread_info *thread) { case S64_TYPE: t.s64 = a.s64 * b.s64; assert(!pI->is_wide()); - //assert(!pI->is_hi()); + // assert(!pI->is_hi()); d.s64 = t.s64; break; case U16_TYPE: @@ -5439,6 +5441,38 @@ void shfl_impl(const ptx_instruction *pI, core_t *core, warp_inst_t inst) { } } +void shf_impl(const ptx_instruction *pI, ptx_thread_info *thread) { + ptx_reg_t a, b, c, d; + const operand_info &dst = pI->dst(); + const operand_info &src1 = pI->src1(); + const operand_info &src2 = pI->src2(); + const operand_info &src3 = pI->src3(); + + // Only b32 is allowed + unsigned i_type = pI->get_type(); + a = thread->get_operand_value(src1, dst, i_type, thread, 1); + b = thread->get_operand_value(src2, dst, i_type, thread, 1); + c = thread->get_operand_value(src3, dst, i_type, thread, 1); + + if (i_type != B32_TYPE) + printf("Only the b32 data_type is allowed per the ISA\n"); + + unsigned clamp_mode = pI->clamp_mode(); + unsigned n = c.u32 & 0x1f; + if (clamp_mode) { + if (c.u32 < 32) + n = c; + else + n = 32; + } + if (pI->left_mode()) + d.u32 = (b.u32 << n) | (a.u32 >> (32 - n)); + else + d.u32 = (b.u32 << (32 - n)) | (a.u32 >> n); + + thread->set_operand_value(dst, d, i_type, thread, pI); +} + void shl_impl(const ptx_instruction *pI, ptx_thread_info *thread) { ptx_reg_t a, b, d; const operand_info &dst = pI->dst(); @@ -6021,6 +6055,17 @@ void tex_impl(const ptx_instruction *pI, ptx_thread_info *thread) { // to be fetched std::string texname = src1.name(); + // If indirect access, use register's value as address + // to find the symbol + if (src1.is_reg()) { + ptx_reg_t src1_data = + thread->get_operand_value(src1, dst, pI->get_type(), thread, 1); + addr_t sym_addr = src1_data.u64; + symbol *texRef = thread->get_symbol_table()->lookup_by_addr(sym_addr); + assert(texRef != NULL); + texname = texRef->name(); + } + unsigned to_type = pI->get_type(); unsigned c_type = pI->get_type2(); fflush(stdout); diff --git a/src/cuda-sim/memory.cc b/src/cuda-sim/memory.cc index 1323837..036bada 100644 --- a/src/cuda-sim/memory.cc +++ b/src/cuda-sim/memory.cc @@ -109,11 +109,11 @@ void memory_space_impl<BSIZE>::read_single_block(mem_addr_t blk_idx, if ((addr + length) > (blk_idx + 1) * BSIZE) { printf( "GPGPU-Sim PTX: ERROR * access to memory \'%s\' is unaligned : " - "addr=0x%x, length=%zu\n", + "addr=0x%llx, length=%zu\n", m_name.c_str(), addr, length); printf( - "GPGPU-Sim PTX: (addr+length)=0x%lx > 0x%x=(index+1)*BSIZE, " - "index=0x%x, BSIZE=0x%x\n", + "GPGPU-Sim PTX: (addr+length)=0x%llx > 0x%llx=(index+1)*BSIZE, " + "index=0x%llx, BSIZE=0x%x\n", (addr + length), (blk_idx + 1) * BSIZE, blk_idx, BSIZE); throw 1; } @@ -169,7 +169,7 @@ void memory_space_impl<BSIZE>::print(const char *format, FILE *fout) const { typename map_t::const_iterator i_page; for (i_page = m_data.begin(); i_page != m_data.end(); ++i_page) { - fprintf(fout, "%s %08x:", m_name.c_str(), i_page->first); + fprintf(fout, "%s %08llx:", m_name.c_str(), i_page->first); i_page->second.print(format, fout); } } diff --git a/src/cuda-sim/opcodes.def b/src/cuda-sim/opcodes.def index f5bf156..83a23ea 100644 --- a/src/cuda-sim/opcodes.def +++ b/src/cuda-sim/opcodes.def @@ -103,6 +103,7 @@ OP_DEF(SELP_OP,selp_impl,"selp",1,1) OP_DEF(SETP_OP,setp_impl,"setp",1,1) OP_DEF(SET_OP,set_impl,"set",1,1) OP_W_DEF(SHFL_OP,shfl_impl,"shfl",1,10) +OP_DEF(SHF_OP,shf_impl,"shf",1,1) OP_DEF(SHL_OP,shl_impl,"shl",1,1) OP_DEF(SHR_OP,shr_impl,"shr",1,1) OP_DEF(SIN_OP,sin_impl,"sin",1,4) diff --git a/src/cuda-sim/ptx.l b/src/cuda-sim/ptx.l index 7706f0b..0810ef6 100644 --- a/src/cuda-sim/ptx.l +++ b/src/cuda-sim/ptx.l @@ -1,6 +1,7 @@ /* -Copyright (c) 2009-2021, Tor M. Aamodt, Vijay Kandiah, Nikos Hardavellas -The University of British Columbia, Northwestern University +Copyright (c) 2009-2021, Tor M. Aamodt, Vijay Kandiah, Nikos Hardavellas, +Mahmoud Khairy, Junrui Pan, Timothy G. Rogers +The University of British Columbia, Northwestern University, Purdue University All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: @@ -133,6 +134,7 @@ selp TC; yylval->int_value = SELP_OP; return OPCODE; setp TC; yylval->int_value = SETP_OP; return OPCODE; set TC; yylval->int_value = SET_OP; return OPCODE; shfl TC; yylval->int_value = SHFL_OP; return OPCODE; +shf TC; yylval->int_value = SHF_OP; return OPCODE; shl TC; yylval->int_value = SHL_OP; return OPCODE; shr TC; yylval->int_value = SHR_OP; return OPCODE; sin TC; yylval->int_value = SIN_OP; return OPCODE; @@ -316,6 +318,9 @@ breakaddr TC; yylval->int_value = BREAKADDR_OP; return OPCODE; \.sat TC; return SAT_OPTION; +\.l TC; return LEFT_OPTION; +\.r TC; return RIGHT_OPTION; + \.eq TC; return EQ_OPTION; \.ne TC; return NE_OPTION; \.lt TC; return LT_OPTION; @@ -353,6 +358,8 @@ breakaddr TC; yylval->int_value = BREAKADDR_OP; return OPCODE; \.arrive TC; return ARRIVE_OPTION; \.red TC; return RED_OPTION; +\.clamp TC; return CLAMP_OPTION; +\.wrap TC; return WRAP_OPTION; \.approx TC; return APPROX_OPTION; \.full TC; return FULL_OPTION; @@ -487,4 +494,4 @@ int ptx_error( yyscan_t yyscanner, ptx_recognizer* recognizer, const char *s ) fflush(stdout); //exit(1); return 0; -}
\ No newline at end of file +} diff --git a/src/cuda-sim/ptx.y b/src/cuda-sim/ptx.y index b38f783..61183e8 100644 --- a/src/cuda-sim/ptx.y +++ b/src/cuda-sim/ptx.y @@ -220,6 +220,10 @@ class ptx_recognizer; %token PRMT_RC16_MODE; %token PRMT_ECL_MODE; %token PRMT_ECR_MODE; +%token WRAP_OPTION; +%token CLAMP_OPTION; +%token LEFT_OPTION; +%token RIGHT_OPTION; %type <int_value> function_decl_header %type <ptr_value> function_decl @@ -507,6 +511,10 @@ option: type_spec | DOWN_OPTION { recognizer->add_option(DOWN_OPTION); } | BFLY_OPTION { recognizer->add_option(BFLY_OPTION); } | IDX_OPTION { recognizer->add_option(IDX_OPTION); } + | WRAP_OPTION { recognizer->add_option(WRAP_OPTION); } + | CLAMP_OPTION { recognizer->add_option(CLAMP_OPTION); } + | LEFT_OPTION { recognizer->add_option(LEFT_OPTION); } + | RIGHT_OPTION { recognizer->add_option(RIGHT_OPTION); } ; atomic_operation_spec: ATOMIC_AND { recognizer->add_option(ATOMIC_AND); } diff --git a/src/cuda-sim/ptx_ir.cc b/src/cuda-sim/ptx_ir.cc index 2edc1ed..4e500cc 100644 --- a/src/cuda-sim/ptx_ir.cc +++ b/src/cuda-sim/ptx_ir.cc @@ -1,17 +1,19 @@ // Copyright (c) 2009-2021, Tor M. Aamodt, Ali Bakhoda, Wilson W.L. Fung, -// George L. Yuan, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// George L. Yuan, Vijay Kandiah, Nikos Hardavellas, +// Mahmoud Khairy, Junrui Pan, Timothy G. Rogers +// The University of British Columbia, Northwestern University, Purdue +// University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -137,6 +139,22 @@ symbol *symbol_table::lookup(const char *identifier) { return NULL; } +symbol *symbol_table::lookup_by_addr(addr_t addr) { + for (auto it = m_symbols.begin(); it != m_symbols.end(); ++it) { + symbol *sym = it->second; + + // check if symbol has the addr to be found + if ((!sym->is_reg()) && (sym->has_valid_address()) && + (sym->get_address() == addr)) { + return sym; + } + } + if (m_parent) { + return m_parent->lookup_by_addr(addr); + } + return NULL; +} + symbol *symbol_table::add_variable(const char *identifier, const type_info *type, unsigned size, const char *filename, unsigned line) { @@ -1225,6 +1243,8 @@ ptx_instruction::ptx_instruction( m_rounding_mode = RN_OPTION; m_compare_op = -1; m_saturation_mode = 0; + m_clamp_mode = 0; + m_left_mode = 0; m_geom_spec = 0; m_vector_spec = 0; m_atomic_spec = 0; @@ -1291,6 +1311,18 @@ ptx_instruction::ptx_instruction( case SAT_OPTION: m_saturation_mode = 1; break; + case WRAP_OPTION: + m_clamp_mode = 0; + break; + case CLAMP_OPTION: + m_clamp_mode = 1; + break; + case LEFT_OPTION: + m_left_mode = 1; + break; + case RIGHT_OPTION: + m_left_mode = 0; + break; case RNI_OPTION: case RZI_OPTION: case RMI_OPTION: @@ -1385,7 +1417,7 @@ ptx_instruction::ptx_instruction( case CS_OPTION: case LU_OPTION: case CV_OPTION: - case WB_OPTION: + case WB_OPTION: case WT_OPTION: m_cache_option = last_ptx_inst_option; break; @@ -1468,8 +1500,8 @@ std::string ptx_instruction::to_string() const { char buf[STR_SIZE]; unsigned used_bytes = 0; if (!is_label()) { - used_bytes += - snprintf(buf + used_bytes, STR_SIZE - used_bytes, " PC=0x%03x ", m_PC); + used_bytes += snprintf(buf + used_bytes, STR_SIZE - used_bytes, + " PC=0x%03llx ", m_PC); } else { used_bytes += snprintf(buf + used_bytes, STR_SIZE - used_bytes, " "); diff --git a/src/cuda-sim/ptx_ir.h b/src/cuda-sim/ptx_ir.h index 8251759..b08a692 100644 --- a/src/cuda-sim/ptx_ir.h +++ b/src/cuda-sim/ptx_ir.h @@ -205,6 +205,7 @@ class symbol { const std::string &name() const { return m_name; } const std::string &decl_location() const { return m_decl_location; } const type_info *type() const { return m_type; } + bool has_valid_address() const { return m_address_valid; } addr_t get_address() const { assert(m_is_label || !m_type->get_key().is_reg()); // todo : other assertions @@ -310,6 +311,7 @@ class symbol_table { void set_ptx_version(float ver, unsigned ext); void set_sm_target(const char *target, const char *ext, const char *ext2); symbol *lookup(const char *identifier); + symbol *lookup_by_addr(addr_t addr); std::string get_scope_name() const { return m_scope_name; } symbol *add_variable(const char *identifier, const type_info *type, unsigned size, const char *filename, unsigned line); @@ -1085,6 +1087,8 @@ class ptx_instruction : public warp_inst_t { unsigned cache_option() const { return m_cache_option; } unsigned rounding_mode() const { return m_rounding_mode; } unsigned saturation_mode() const { return m_saturation_mode; } + unsigned clamp_mode() const { return m_clamp_mode; } + unsigned left_mode() const { return m_left_mode; } unsigned dimension() const { return m_geom_spec; } unsigned barrier_op() const { return m_barrier_op; } unsigned shfl_op() const { return m_shfl_op; } @@ -1159,6 +1163,8 @@ class ptx_instruction : public warp_inst_t { unsigned m_rounding_mode; unsigned m_compare_op; unsigned m_saturation_mode; + unsigned m_clamp_mode; + unsigned m_left_mode; unsigned m_barrier_op; unsigned m_shfl_op; unsigned m_prmt_op; @@ -1248,6 +1254,7 @@ class function_info { const ptx_version &get_ptx_version() const { return m_symtab->get_ptx_version(); } + virtual ~function_info() {} unsigned get_sm_target() const { return m_symtab->get_sm_target(); } bool is_extern() const { return m_extern; } void set_name(const char *name) { m_name = name; } diff --git a/src/cuda-sim/ptx_loader.cc b/src/cuda-sim/ptx_loader.cc index 4e91763..df35498 100644 --- a/src/cuda-sim/ptx_loader.cc +++ b/src/cuda-sim/ptx_loader.cc @@ -95,7 +95,7 @@ void gpgpu_context::print_ptx_file(const char *p, unsigned source_num, const ptx_instruction *pI = ptx_parser->ptx_instruction_lookup(filename, n); char pc[64]; if (pI && pI->get_PC()) - snprintf(pc, 64, "%4u", pI->get_PC()); + snprintf(pc, 64, "%4llu", pI->get_PC()); else snprintf(pc, 64, " "); printf(" _%u.ptx %4u (pc=%s): %s\n", source_num, n, pc, t); @@ -240,7 +240,7 @@ void fix_duplicate_errors(char fname2[1024]) { unsigned oldlinenum = 1; unsigned linenum; char *startptr = ptxdata; - char *funcptr; + char *funcptr = NULL; char *tempptr = ptxdata - 1; char *lineptr = ptxdata - 1; @@ -320,7 +320,7 @@ void fix_duplicate_errors(char fname2[1024]) { // we need the application name here too. char *get_app_binary_name() { char exe_path[1025]; - char *self_exe_path; + char *self_exe_path = NULL; #ifdef __APPLE__ // AMRUTH: get apple device and check the result. printf("WARNING: not tested for Apple-mac devices \n"); diff --git a/src/cuda-sim/ptx_parser.cc b/src/cuda-sim/ptx_parser.cc index 86a33c2..a80eeae 100644 --- a/src/cuda-sim/ptx_parser.cc +++ b/src/cuda-sim/ptx_parser.cc @@ -206,7 +206,7 @@ void ptx_recognizer::end_function() { gpgpu_ptx_assemble(g_func_info->get_name(), g_func_info); g_current_symbol_table = g_global_symbol_table; - PTX_PARSE_DPRINTF("function %s, PC = %d\n", g_func_info->get_name().c_str(), + PTX_PARSE_DPRINTF("function %s, PC = %llu\n", g_func_info->get_name().c_str(), g_func_info->get_start_PC()); } @@ -486,7 +486,7 @@ void ptx_recognizer::add_identifier(const char *identifier, int array_dim, case param_space_local: printf( "GPGPU-Sim PTX: allocating stack frame region for .param \"%s\" from " - "0x%x to 0x%lx\n", + "0x%llx to 0x%llx\n", identifier, g_current_symbol_table->get_local_next(), g_current_symbol_table->get_local_next() + num_bits / 8); fflush(stdout); @@ -521,7 +521,7 @@ void ptx_recognizer::add_constptr(const char *identifier1, unsigned addr = s2->get_address(); - printf("GPGPU-Sim PTX: moving \"%s\" from 0x%x to 0x%x (%s+%x)\n", + printf("GPGPU-Sim PTX: moving \"%s\" from 0x%llx to 0x%x (%s+%d)\n", identifier1, s1->get_address(), addr + offset, identifier2, offset); s1->set_address(addr + offset); diff --git a/src/cuda-sim/ptx_sim.cc b/src/cuda-sim/ptx_sim.cc index dc801f8..2a548ee 100644 --- a/src/cuda-sim/ptx_sim.cc +++ b/src/cuda-sim/ptx_sim.cc @@ -369,7 +369,8 @@ static void print_reg(FILE *fp, std::string name, ptx_reg_t value, fprintf(fp, ".u64 %llu [0x%llx]\n", value.u64, value.u64); break; case F16_TYPE: - fprintf(fp, ".f16 %f [0x%04x]\n", value.f16, (unsigned)value.u16); + fprintf(fp, ".f16 %f [0x%04x]\n", static_cast<float>(value.f16), + (unsigned)value.u16); break; case F32_TYPE: fprintf(fp, ".f32 %.15lf [0x%08x]\n", value.f32, value.u32); diff --git a/src/cuda-sim/ptx_sim.h b/src/cuda-sim/ptx_sim.h index f0c26ef..8eec922 100644 --- a/src/cuda-sim/ptx_sim.h +++ b/src/cuda-sim/ptx_sim.h @@ -459,6 +459,9 @@ class ptx_thread_info { // Jin: get corresponding kernel grid for CDP purpose kernel_info_t &get_kernel() { return m_kernel; } + // Weili: access symbol_table + symbol_table *get_symbol_table() { return m_symbol_table; } + public: addr_t m_last_effective_address; bool m_branch_taken; diff --git a/src/debug.cc b/src/debug.cc index 29506bd..8cc5e1f 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -124,7 +124,7 @@ void gpgpu_sim::gpgpu_debug() { fflush(stdout); char line[1024]; - fgets(line, 1024, stdin); + char *ptr = fgets(line, 1024, stdin); char *tok = strtok(line, " \t\n"); if (!strcmp(tok, "dp")) { @@ -136,7 +136,11 @@ void gpgpu_sim::gpgpu_debug() { fflush(stdout); } else if (!strcmp(tok, "q") || !strcmp(tok, "quit")) { printf("\nreally quit GPGPU-Sim (y/n)?\n"); - fgets(line, 1024, stdin); + ptr = fgets(line, 1024, stdin); + if (ptr == NULL) { + printf("can't read input\n"); + exit(0); + } tok = strtok(line, " \t\n"); if (!strcmp(tok, "y")) { exit(0); diff --git a/src/gpgpu-sim/CMakeLists.txt b/src/gpgpu-sim/CMakeLists.txt new file mode 100644 index 0000000..04f1973 --- /dev/null +++ b/src/gpgpu-sim/CMakeLists.txt @@ -0,0 +1,36 @@ +# Exclude power_interface.cc if no power model +list(APPEND gpgpusim_SRC addrdec.cc + dram.cc + dram_sched.cc + gpu-cache.cc + gpu-misc.cc + gpu-sim.cc + hashing.cc + histogram.cc + icnt_wrapper.cc + l2cache.cc + local_interconnect.cc + mem_fetch.cc + mem_latency_stat.cc + power_interface.cc + power_stat.cc + scoreboard.cc + shader.cc + stack.cc + stat-tool.cc + traffic_breakdown.cc + visualizer.cc) +if(NOT GPGPUSIM_USE_POWER_MODEL) + list(REMOVE_ITEM ${gpgpusim_SRC} power_interface.cc) +endif() + +# Create libgpgpusim.a +add_library(gpgpusim STATIC ${gpgpusim_SRC}) +target_include_directories(gpgpusim PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) +target_include_directories(gpgpusim PUBLIC ${CUDAToolkit_INCLUDE_DIRS}) + +if(GPGPUSIM_USE_POWER_MODEL) +target_compile_definitions(gpgpusim PRIVATE GPGPUSIM_POWER_MODEL) +target_include_directories(gpgpusim PRIVATE ${GPGPUSIM_POWER_MODEL}) +endif() + diff --git a/src/gpgpu-sim/addrdec.cc b/src/gpgpu-sim/addrdec.cc index 19714ec..db27c82 100644 --- a/src/gpgpu-sim/addrdec.cc +++ b/src/gpgpu-sim/addrdec.cc @@ -519,7 +519,7 @@ void linear_to_raw_address_translation::sweep_test() const { h->second, raw_addr); abort(); } else { - assert((int)tlx.chip < m_n_channel); + assert(tlx.chip < m_n_channel); // ensure that partition_address() returns the concatenated address if ((ADDR_CHIP_S != -1 and raw_addr >= (1ULL << ADDR_CHIP_S)) or (ADDR_CHIP_S == -1 and raw_addr >= (1ULL << addrdec_mklow[CHIP]))) { @@ -584,7 +584,7 @@ unsigned next_powerOf2(unsigned n) { n = n - 1; // do till only one bit is left - while (n & n - 1) n = n & (n - 1); // unset rightmost bit + while (n & (n - 1)) n = n & (n - 1); // unset rightmost bit // n is now a power of two (less than n) diff --git a/src/gpgpu-sim/dram.cc b/src/gpgpu-sim/dram.cc index 545c45d..80e20d7 100644 --- a/src/gpgpu-sim/dram.cc +++ b/src/gpgpu-sim/dram.cc @@ -1,17 +1,19 @@ // Copyright (c) 2009-2021, Tor M. Aamodt, Wilson W.L. Fung, Ali Bakhoda, -// Ivan Sham, George L. Yuan, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// Ivan Sham, George L. Yuan, Vijay Kandiah, Nikos Hardavellas, +// Mahmoud Khairy, Junrui Pan, Timothy G. Rogers +// The University of British Columbia, Northwestern University, Purdue +// University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -591,39 +593,40 @@ bool dram_t::issue_col_command(int j) { bk[j]->mrq = NULL; } } else - // correct row activated for a WRITE - if (!issued && !CCDc && !bk[j]->RCDWRc && !(bkgrp[grp]->CCDLc) && - (bk[j]->curr_row == bk[j]->mrq->row) && (bk[j]->mrq->rw == WRITE) && - (RTWc == 0) && (bk[j]->state == BANK_ACTIVE) && !rwq->full()) { - if (rw == READ) { - rw = WRITE; - rwq->set_min_length(m_config->WL); - } - rwq->push(bk[j]->mrq); + // correct row activated for a WRITE + if (!issued && !CCDc && !bk[j]->RCDWRc && !(bkgrp[grp]->CCDLc) && + (bk[j]->curr_row == bk[j]->mrq->row) && (bk[j]->mrq->rw == WRITE) && + (RTWc == 0) && (bk[j]->state == BANK_ACTIVE) && !rwq->full()) { + if (rw == READ) { + rw = WRITE; + rwq->set_min_length(m_config->WL); + } + rwq->push(bk[j]->mrq); - bk[j]->mrq->txbytes += m_config->dram_atom_size; - CCDc = m_config->tCCD; - bkgrp[grp]->CCDLc = m_config->tCCDL; - WTRc = m_config->tWTR; - bk[j]->WTPc = m_config->tWTP; - issued = true; + bk[j]->mrq->txbytes += m_config->dram_atom_size; + CCDc = m_config->tCCD; + bkgrp[grp]->CCDLc = m_config->tCCDL; + WTRc = m_config->tWTR; + bk[j]->WTPc = m_config->tWTP; + issued = true; - if (bk[j]->mrq->data->get_access_type() == L2_WRBK_ACC) - n_wr_WB++; - else - n_wr++; - bwutil += m_config->BL / m_config->data_command_freq_ratio; - bwutil_partial += m_config->BL / m_config->data_command_freq_ratio; + if (bk[j]->mrq->data->get_access_type() == L2_WRBK_ACC) + n_wr_WB++; + else + n_wr++; + bwutil += m_config->BL / m_config->data_command_freq_ratio; + bwutil_partial += m_config->BL / m_config->data_command_freq_ratio; #ifdef DRAM_VERIFY - PRINT_CYCLE = 1; - printf("\tWR Bk:%d Row:%03x Col:%03x \n", j, bk[j]->curr_row, - bk[j]->mrq->col + bk[j]->mrq->txbytes - m_config->dram_atom_size); + PRINT_CYCLE = 1; + printf( + "\tWR Bk:%d Row:%03x Col:%03x \n", j, bk[j]->curr_row, + bk[j]->mrq->col + bk[j]->mrq->txbytes - m_config->dram_atom_size); #endif - // transfer done - if (!(bk[j]->mrq->txbytes < bk[j]->mrq->nbytes)) { - bk[j]->mrq = NULL; + // transfer done + if (!(bk[j]->mrq->txbytes < bk[j]->mrq->nbytes)) { + bk[j]->mrq = NULL; + } } - } } return issued; @@ -659,23 +662,23 @@ bool dram_t::issue_row_command(int j) { } else - // different row activated - if ((!issued) && (bk[j]->curr_row != bk[j]->mrq->row) && - (bk[j]->state == BANK_ACTIVE) && - (!bk[j]->RASc && !bk[j]->WTPc && !bk[j]->RTPc && - !bkgrp[grp]->RTPLc)) { - // make the bank idle again - bk[j]->state = BANK_IDLE; - bk[j]->RPc = m_config->tRP; - prio = (j + 1) % m_config->nbk; - issued = true; - n_pre++; - n_pre_partial++; + // different row activated + if ((!issued) && (bk[j]->curr_row != bk[j]->mrq->row) && + (bk[j]->state == BANK_ACTIVE) && + (!bk[j]->RASc && !bk[j]->WTPc && !bk[j]->RTPc && + !bkgrp[grp]->RTPLc)) { + // make the bank idle again + bk[j]->state = BANK_IDLE; + bk[j]->RPc = m_config->tRP; + prio = (j + 1) % m_config->nbk; + issued = true; + n_pre++; + n_pre_partial++; #ifdef DRAM_VERIFY - PRINT_CYCLE = 1; - printf("\tPRE BK:%d Row:%03x \n", j, bk[j]->curr_row); + PRINT_CYCLE = 1; + printf("\tPRE BK:%d Row:%03x \n", j, bk[j]->curr_row); #endif - } + } } return issued; } @@ -879,4 +882,5 @@ unsigned dram_t::get_bankgrp_number(unsigned i) { } else { assert(1); } + return 0; // we should never get here } diff --git a/src/gpgpu-sim/dram.h b/src/gpgpu-sim/dram.h index 88e46ed..9e9517b 100644 --- a/src/gpgpu-sim/dram.h +++ b/src/gpgpu-sim/dram.h @@ -1,17 +1,19 @@ // Copyright (c) 2009-2021, Tor M. Aamodt, Ivan Sham, Ali Bakhoda, -// George L. Yuan, Wilson W.L. Fung, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// George L. Yuan, Wilson W.L. Fung, Vijay Kandiah, Nikos Hardavellas, +// Mahmoud Khairy, Junrui Pan, Timothy G. Rogers +// The University of British Columbia, Northwestern University, Purdue +// University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. diff --git a/src/gpgpu-sim/gpu-cache.cc b/src/gpgpu-sim/gpu-cache.cc index a2aeec5..0ea9ff6 100644 --- a/src/gpgpu-sim/gpu-cache.cc +++ b/src/gpgpu-sim/gpu-cache.cc @@ -1,16 +1,19 @@ -// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington, +// Vijay Kandiah, Nikos Hardavellas, Mahmoud Khairy, Junrui Pan, +// Timothy G. Rogers +// The University of British Columbia, Northwestern University, Purdue +// University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -285,10 +288,11 @@ enum cache_request_status tag_array::probe(new_addr_type addr, unsigned &idx, // number of dirty lines / total lines in the cache float dirty_line_percentage = ((float)m_dirty / (m_config.m_nset * m_config.m_assoc)) * 100; - // If the cacheline is from a load op (not modified), + // If the cacheline is from a load op (not modified), // or the total dirty cacheline is above a specific value, - // Then this cacheline is eligible to be considered for replacement candidate - // i.e. Only evict clean cachelines until total dirty cachelines reach the limit. + // Then this cacheline is eligible to be considered for replacement + // candidate i.e. Only evict clean cachelines until total dirty cachelines + // reach the limit. if (!line->is_modified_line() || dirty_line_percentage >= m_config.m_wr_percent) { all_reserved = false; @@ -407,6 +411,11 @@ void tag_array::fill(new_addr_type addr, unsigned time, // assert( m_config.m_alloc_policy == ON_FILL ); unsigned idx; enum cache_request_status status = probe(addr, idx, mask, is_write); + + if (status == RESERVATION_FAIL) { + return; + } + bool before = m_lines[idx]->is_modified_line(); // assert(status==MISS||status==SECTOR_MISS); // MSHR should have prevented // redundant memory request @@ -430,7 +439,8 @@ void tag_array::fill(new_addr_type addr, unsigned time, void tag_array::fill(unsigned index, unsigned time, mem_fetch *mf) { assert(m_config.m_alloc_policy == ON_MISS); bool before = m_lines[index]->is_modified_line(); - m_lines[index]->fill(time, mf->get_access_sector_mask(), mf->get_access_byte_mask()); + m_lines[index]->fill(time, mf->get_access_sector_mask(), + mf->get_access_byte_mask()); if (m_lines[index]->is_modified_line() && !before) { m_dirty++; } @@ -624,14 +634,6 @@ void mshr_table::display(FILE *fp) const { /***************************************************************** Caches * *****************************************************************/ cache_stats::cache_stats() { - m_stats.resize(NUM_MEM_ACCESS_TYPE); - m_stats_pw.resize(NUM_MEM_ACCESS_TYPE); - m_fail_stats.resize(NUM_MEM_ACCESS_TYPE); - for (unsigned i = 0; i < NUM_MEM_ACCESS_TYPE; ++i) { - m_stats[i].resize(NUM_CACHE_REQUEST_STATUS, 0); - m_stats_pw[i].resize(NUM_CACHE_REQUEST_STATUS, 0); - m_fail_stats[i].resize(NUM_CACHE_RESERVATION_FAIL_STATUS, 0); - } m_cache_port_available_cycles = 0; m_cache_data_port_busy_cycles = 0; m_cache_fill_port_busy_cycles = 0; @@ -641,11 +643,10 @@ void cache_stats::clear() { /// /// Zero out all current cache statistics /// - for (unsigned i = 0; i < NUM_MEM_ACCESS_TYPE; ++i) { - std::fill(m_stats[i].begin(), m_stats[i].end(), 0); - std::fill(m_stats_pw[i].begin(), m_stats_pw[i].end(), 0); - std::fill(m_fail_stats[i].begin(), m_fail_stats[i].end(), 0); - } + m_stats.clear(); + m_stats_pw.clear(); + m_fail_stats.clear(); + m_cache_port_available_cycles = 0; m_cache_data_port_busy_cycles = 0; m_cache_fill_port_busy_cycles = 0; @@ -655,35 +656,67 @@ void cache_stats::clear_pw() { /// /// Zero out per-window cache statistics /// - for (unsigned i = 0; i < NUM_MEM_ACCESS_TYPE; ++i) { - std::fill(m_stats_pw[i].begin(), m_stats_pw[i].end(), 0); - } + m_stats_pw.clear(); } -void cache_stats::inc_stats(int access_type, int access_outcome) { +void cache_stats::inc_stats(int access_type, int access_outcome, + unsigned long long streamID) { /// /// Increment the stat corresponding to (access_type, access_outcome) by 1. /// if (!check_valid(access_type, access_outcome)) assert(0 && "Unknown cache access type or access outcome"); - m_stats[access_type][access_outcome]++; + if (m_stats.find(streamID) == m_stats.end()) { + std::vector<std::vector<unsigned long long>> new_val; + new_val.resize(NUM_MEM_ACCESS_TYPE); + for (unsigned j = 0; j < NUM_MEM_ACCESS_TYPE; ++j) { + new_val[j].resize(NUM_CACHE_REQUEST_STATUS, 0); + } + m_stats.insert(std::pair<unsigned long long, + std::vector<std::vector<unsigned long long>>>( + streamID, new_val)); + } + m_stats.at(streamID)[access_type][access_outcome]++; } -void cache_stats::inc_stats_pw(int access_type, int access_outcome) { +void cache_stats::inc_stats_pw(int access_type, int access_outcome, + unsigned long long streamID) { /// /// Increment the corresponding per-window cache stat /// if (!check_valid(access_type, access_outcome)) assert(0 && "Unknown cache access type or access outcome"); - m_stats_pw[access_type][access_outcome]++; + + if (m_stats_pw.find(streamID) == m_stats_pw.end()) { + std::vector<std::vector<unsigned long long>> new_val; + new_val.resize(NUM_MEM_ACCESS_TYPE); + for (unsigned j = 0; j < NUM_MEM_ACCESS_TYPE; ++j) { + new_val[j].resize(NUM_CACHE_REQUEST_STATUS, 0); + } + m_stats_pw.insert(std::pair<unsigned long long, + std::vector<std::vector<unsigned long long>>>( + streamID, new_val)); + } + m_stats_pw.at(streamID)[access_type][access_outcome]++; } -void cache_stats::inc_fail_stats(int access_type, int fail_outcome) { +void cache_stats::inc_fail_stats(int access_type, int fail_outcome, + unsigned long long streamID) { if (!check_fail_valid(access_type, fail_outcome)) assert(0 && "Unknown cache access type or access fail"); - m_fail_stats[access_type][fail_outcome]++; + if (m_fail_stats.find(streamID) == m_fail_stats.end()) { + std::vector<std::vector<unsigned long long>> new_val; + new_val.resize(NUM_MEM_ACCESS_TYPE); + for (unsigned j = 0; j < NUM_MEM_ACCESS_TYPE; ++j) { + new_val[j].resize(NUM_CACHE_RESERVATION_FAIL_STATUS, 0); + } + m_fail_stats.insert(std::pair<unsigned long long, + std::vector<std::vector<unsigned long long>>>( + streamID, new_val)); + } + m_fail_stats.at(streamID)[access_type][fail_outcome]++; } enum cache_request_status cache_stats::select_stats_status( @@ -702,7 +735,8 @@ enum cache_request_status cache_stats::select_stats_status( } unsigned long long &cache_stats::operator()(int access_type, int access_outcome, - bool fail_outcome) { + bool fail_outcome, + unsigned long long streamID) { /// /// Simple method to read/modify the stat corresponding to (access_type, /// access_outcome) Used overloaded () to avoid the need for separate @@ -712,17 +746,18 @@ unsigned long long &cache_stats::operator()(int access_type, int access_outcome, if (!check_fail_valid(access_type, access_outcome)) assert(0 && "Unknown cache access type or fail outcome"); - return m_fail_stats[access_type][access_outcome]; + return m_fail_stats.at(streamID)[access_type][access_outcome]; } else { if (!check_valid(access_type, access_outcome)) assert(0 && "Unknown cache access type or access outcome"); - return m_stats[access_type][access_outcome]; + return m_stats.at(streamID)[access_type][access_outcome]; } } unsigned long long cache_stats::operator()(int access_type, int access_outcome, - bool fail_outcome) const { + bool fail_outcome, + unsigned long long streamID) const { /// /// Const accessor into m_stats. /// @@ -730,12 +765,12 @@ unsigned long long cache_stats::operator()(int access_type, int access_outcome, if (!check_fail_valid(access_type, access_outcome)) assert(0 && "Unknown cache access type or fail outcome"); - return m_fail_stats[access_type][access_outcome]; + return m_fail_stats.at(streamID)[access_type][access_outcome]; } else { if (!check_valid(access_type, access_outcome)) assert(0 && "Unknown cache access type or access outcome"); - return m_stats[access_type][access_outcome]; + return m_stats.at(streamID)[access_type][access_outcome]; } } @@ -744,15 +779,74 @@ cache_stats cache_stats::operator+(const cache_stats &cs) { /// Overloaded + operator to allow for simple stat accumulation /// cache_stats ret; - for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { - for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) { - ret(type, status, false) = - m_stats[type][status] + cs(type, status, false); + for (auto iter = m_stats.begin(); iter != m_stats.end(); ++iter) { + unsigned long long streamID = iter->first; + ret.m_stats.insert(std::pair<unsigned long long, + std::vector<std::vector<unsigned long long>>>( + streamID, m_stats.at(streamID))); + } + for (auto iter = m_stats_pw.begin(); iter != m_stats_pw.end(); ++iter) { + unsigned long long streamID = iter->first; + ret.m_stats_pw.insert( + std::pair<unsigned long long, + std::vector<std::vector<unsigned long long>>>( + streamID, m_stats_pw.at(streamID))); + } + for (auto iter = m_fail_stats.begin(); iter != m_fail_stats.end(); ++iter) { + unsigned long long streamID = iter->first; + ret.m_fail_stats.insert( + std::pair<unsigned long long, + std::vector<std::vector<unsigned long long>>>( + streamID, m_fail_stats.at(streamID))); + } + for (auto iter = cs.m_stats.begin(); iter != cs.m_stats.end(); ++iter) { + unsigned long long streamID = iter->first; + if (ret.m_stats.find(streamID) == ret.m_stats.end()) { + ret.m_stats.insert( + std::pair<unsigned long long, + std::vector<std::vector<unsigned long long>>>( + streamID, cs.m_stats.at(streamID))); + } else { + for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { + for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) { + ret.m_stats.at(streamID)[type][status] += + cs(type, status, false, streamID); + } + } } - for (unsigned status = 0; status < NUM_CACHE_RESERVATION_FAIL_STATUS; - ++status) { - ret(type, status, true) = - m_fail_stats[type][status] + cs(type, status, true); + } + for (auto iter = cs.m_stats_pw.begin(); iter != cs.m_stats_pw.end(); ++iter) { + unsigned long long streamID = iter->first; + if (ret.m_stats_pw.find(streamID) == ret.m_stats_pw.end()) { + ret.m_stats_pw.insert( + std::pair<unsigned long long, + std::vector<std::vector<unsigned long long>>>( + streamID, cs.m_stats_pw.at(streamID))); + } else { + for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { + for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) { + ret.m_stats_pw.at(streamID)[type][status] += + cs(type, status, false, streamID); + } + } + } + } + for (auto iter = cs.m_fail_stats.begin(); iter != cs.m_fail_stats.end(); + ++iter) { + unsigned long long streamID = iter->first; + if (ret.m_fail_stats.find(streamID) == ret.m_fail_stats.end()) { + ret.m_fail_stats.insert( + std::pair<unsigned long long, + std::vector<std::vector<unsigned long long>>>( + streamID, cs.m_fail_stats.at(streamID))); + } else { + for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { + for (unsigned status = 0; status < NUM_CACHE_RESERVATION_FAIL_STATUS; + ++status) { + ret.m_fail_stats.at(streamID)[type][status] += + cs(type, status, true, streamID); + } + } } } ret.m_cache_port_available_cycles = @@ -768,16 +862,52 @@ cache_stats &cache_stats::operator+=(const cache_stats &cs) { /// /// Overloaded += operator to allow for simple stat accumulation /// - for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { - for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) { - m_stats[type][status] += cs(type, status, false); + for (auto iter = cs.m_stats.begin(); iter != cs.m_stats.end(); ++iter) { + unsigned long long streamID = iter->first; + if (m_stats.find(streamID) == m_stats.end()) { + m_stats.insert(std::pair<unsigned long long, + std::vector<std::vector<unsigned long long>>>( + streamID, cs.m_stats.at(streamID))); + } else { + for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { + for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) { + m_stats.at(streamID)[type][status] += + cs(type, status, false, streamID); + } + } } - for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) { - m_stats_pw[type][status] += cs(type, status, false); + } + for (auto iter = cs.m_stats_pw.begin(); iter != cs.m_stats_pw.end(); ++iter) { + unsigned long long streamID = iter->first; + if (m_stats_pw.find(streamID) == m_stats_pw.end()) { + m_stats_pw.insert(std::pair<unsigned long long, + std::vector<std::vector<unsigned long long>>>( + streamID, cs.m_stats_pw.at(streamID))); + } else { + for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { + for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) { + m_stats_pw.at(streamID)[type][status] += + cs(type, status, false, streamID); + } + } } - for (unsigned status = 0; status < NUM_CACHE_RESERVATION_FAIL_STATUS; - ++status) { - m_fail_stats[type][status] += cs(type, status, true); + } + for (auto iter = cs.m_fail_stats.begin(); iter != cs.m_fail_stats.end(); + ++iter) { + unsigned long long streamID = iter->first; + if (m_fail_stats.find(streamID) == m_fail_stats.end()) { + m_fail_stats.insert( + std::pair<unsigned long long, + std::vector<std::vector<unsigned long long>>>( + streamID, cs.m_fail_stats.at(streamID))); + } else { + for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { + for (unsigned status = 0; status < NUM_CACHE_RESERVATION_FAIL_STATUS; + ++status) { + m_fail_stats.at(streamID)[type][status] += + cs(type, status, true, streamID); + } + } } } m_cache_port_available_cycles += cs.m_cache_port_available_cycles; @@ -786,46 +916,65 @@ cache_stats &cache_stats::operator+=(const cache_stats &cs) { return *this; } -void cache_stats::print_stats(FILE *fout, const char *cache_name) const { +void cache_stats::print_stats(FILE *fout, unsigned long long streamID, + const char *cache_name) const { /// - /// Print out each non-zero cache statistic for every memory access type and - /// status "cache_name" defaults to "Cache_stats" when no argument is - /// provided, otherwise the provided name is used. The printed format is + /// For a given CUDA stream, print out each non-zero cache statistic for every + /// memory access type and status "cache_name" defaults to "Cache_stats" when + /// no argument is provided, otherwise the provided name is used. The printed + /// format is /// "<cache_name>[<request_type>][<request_status>] = <stat_value>" - /// + /// Specify streamID to be -1 to print every stream. + std::vector<unsigned> total_access; - total_access.resize(NUM_MEM_ACCESS_TYPE, 0); std::string m_cache_name = cache_name; - for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { - for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) { - fprintf(fout, "\t%s[%s][%s] = %llu\n", m_cache_name.c_str(), - mem_access_type_str((enum mem_access_type)type), - cache_request_status_str((enum cache_request_status)status), - m_stats[type][status]); + for (auto iter = m_stats.begin(); iter != m_stats.end(); ++iter) { + unsigned long long streamid = iter->first; + // when streamID is specified, skip stats for all other streams, otherwise, + // print stats from all streams + if ((streamID != -1) && (streamid != streamID)) continue; + total_access.clear(); + total_access.resize(NUM_MEM_ACCESS_TYPE, 0); + for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { + for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) { + fprintf(fout, "\t%s[%s][%s] = %llu\n", m_cache_name.c_str(), + mem_access_type_str((enum mem_access_type)type), + cache_request_status_str((enum cache_request_status)status), + m_stats.at(streamid)[type][status]); - if (status != RESERVATION_FAIL && status != MSHR_HIT) - // MSHR_HIT is a special type of SECTOR_MISS - // so its already included in the SECTOR_MISS - total_access[type] += m_stats[type][status]; + if (status != RESERVATION_FAIL && status != MSHR_HIT) + // MSHR_HIT is a special type of SECTOR_MISS + // so its already included in the SECTOR_MISS + total_access[type] += m_stats.at(streamid)[type][status]; + } + } + for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { + if (total_access[type] > 0) + fprintf(fout, "\t%s[%s][%s] = %u\n", m_cache_name.c_str(), + mem_access_type_str((enum mem_access_type)type), "TOTAL_ACCESS", + total_access[type]); } - } - for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { - if (total_access[type] > 0) - fprintf(fout, "\t%s[%s][%s] = %u\n", m_cache_name.c_str(), - mem_access_type_str((enum mem_access_type)type), "TOTAL_ACCESS", - total_access[type]); } } -void cache_stats::print_fail_stats(FILE *fout, const char *cache_name) const { +void cache_stats::print_fail_stats(FILE *fout, unsigned long long streamID, + const char *cache_name) const { std::string m_cache_name = cache_name; - for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { - for (unsigned fail = 0; fail < NUM_CACHE_RESERVATION_FAIL_STATUS; ++fail) { - if (m_fail_stats[type][fail] > 0) { - fprintf(fout, "\t%s[%s][%s] = %llu\n", m_cache_name.c_str(), - mem_access_type_str((enum mem_access_type)type), - cache_fail_status_str((enum cache_reservation_fail_reason)fail), - m_fail_stats[type][fail]); + for (auto iter = m_fail_stats.begin(); iter != m_fail_stats.end(); ++iter) { + unsigned long long streamid = iter->first; + // when streamID is specified, skip stats for all other streams, otherwise, + // print stats from all streams + if ((streamID != -1) && (streamid != streamID)) continue; + for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { + for (unsigned fail = 0; fail < NUM_CACHE_RESERVATION_FAIL_STATUS; + ++fail) { + if (m_fail_stats.at(streamid)[type][fail] > 0) { + fprintf( + fout, "\t%s[%s][%s] = %llu\n", m_cache_name.c_str(), + mem_access_type_str((enum mem_access_type)type), + cache_fail_status_str((enum cache_reservation_fail_reason)fail), + m_fail_stats.at(streamid)[type][fail]); + } } } } @@ -856,11 +1005,14 @@ unsigned long long cache_stats::get_stats( /// cache_request_statuses. /// unsigned long long total = 0; - for (unsigned type = 0; type < num_access_type; ++type) { - for (unsigned status = 0; status < num_access_status; ++status) { - if (!check_valid((int)access_type[type], (int)access_status[status])) - assert(0 && "Unknown cache access type or access outcome"); - total += m_stats[access_type[type]][access_status[status]]; + for (auto iter = m_stats.begin(); iter != m_stats.end(); ++iter) { + unsigned long long streamID = iter->first; + for (unsigned type = 0; type < num_access_type; ++type) { + for (unsigned status = 0; status < num_access_status; ++status) { + if (!check_valid((int)access_type[type], (int)access_status[status])) + assert(0 && "Unknown cache access type or access outcome"); + total += m_stats.at(streamID)[access_type[type]][access_status[status]]; + } } } return total; @@ -873,18 +1025,23 @@ void cache_stats::get_sub_stats(struct cache_sub_stats &css) const { struct cache_sub_stats t_css; t_css.clear(); - for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { - for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) { - if (status == HIT || status == MISS || status == SECTOR_MISS || - status == HIT_RESERVED) - t_css.accesses += m_stats[type][status]; + for (auto iter = m_stats.begin(); iter != m_stats.end(); ++iter) { + unsigned long long streamID = iter->first; + for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { + for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) { + if (status == HIT || status == MISS || status == SECTOR_MISS || + status == HIT_RESERVED) + t_css.accesses += m_stats.at(streamID)[type][status]; - if (status == MISS || status == SECTOR_MISS) - t_css.misses += m_stats[type][status]; + if (status == MISS || status == SECTOR_MISS) + t_css.misses += m_stats.at(streamID)[type][status]; - if (status == HIT_RESERVED) t_css.pending_hits += m_stats[type][status]; + if (status == HIT_RESERVED) + t_css.pending_hits += m_stats.at(streamID)[type][status]; - if (status == RESERVATION_FAIL) t_css.res_fails += m_stats[type][status]; + if (status == RESERVATION_FAIL) + t_css.res_fails += m_stats.at(streamID)[type][status]; + } } } @@ -902,41 +1059,48 @@ void cache_stats::get_sub_stats_pw(struct cache_sub_stats_pw &css) const { struct cache_sub_stats_pw t_css; t_css.clear(); - for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { - for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) { - if (status == HIT || status == MISS || status == SECTOR_MISS || - status == HIT_RESERVED) - t_css.accesses += m_stats_pw[type][status]; + for (auto iter = m_stats_pw.begin(); iter != m_stats_pw.end(); ++iter) { + unsigned long long streamID = iter->first; + for (unsigned type = 0; type < NUM_MEM_ACCESS_TYPE; ++type) { + for (unsigned status = 0; status < NUM_CACHE_REQUEST_STATUS; ++status) { + if (status == HIT || status == MISS || status == SECTOR_MISS || + status == HIT_RESERVED) + t_css.accesses += m_stats_pw.at(streamID)[type][status]; - if (status == HIT) { - if (type == GLOBAL_ACC_R || type == CONST_ACC_R || type == INST_ACC_R) { - t_css.read_hits += m_stats_pw[type][status]; - } else if (type == GLOBAL_ACC_W) { - t_css.write_hits += m_stats_pw[type][status]; + if (status == HIT) { + if (type == GLOBAL_ACC_R || type == CONST_ACC_R || + type == INST_ACC_R) { + t_css.read_hits += m_stats_pw.at(streamID)[type][status]; + } else if (type == GLOBAL_ACC_W) { + t_css.write_hits += m_stats_pw.at(streamID)[type][status]; + } } - } - if (status == MISS || status == SECTOR_MISS) { - if (type == GLOBAL_ACC_R || type == CONST_ACC_R || type == INST_ACC_R) { - t_css.read_misses += m_stats_pw[type][status]; - } else if (type == GLOBAL_ACC_W) { - t_css.write_misses += m_stats_pw[type][status]; + if (status == MISS || status == SECTOR_MISS) { + if (type == GLOBAL_ACC_R || type == CONST_ACC_R || + type == INST_ACC_R) { + t_css.read_misses += m_stats_pw.at(streamID)[type][status]; + } else if (type == GLOBAL_ACC_W) { + t_css.write_misses += m_stats_pw.at(streamID)[type][status]; + } } - } - if (status == HIT_RESERVED) { - if (type == GLOBAL_ACC_R || type == CONST_ACC_R || type == INST_ACC_R) { - t_css.read_pending_hits += m_stats_pw[type][status]; - } else if (type == GLOBAL_ACC_W) { - t_css.write_pending_hits += m_stats_pw[type][status]; + if (status == HIT_RESERVED) { + if (type == GLOBAL_ACC_R || type == CONST_ACC_R || + type == INST_ACC_R) { + t_css.read_pending_hits += m_stats_pw.at(streamID)[type][status]; + } else if (type == GLOBAL_ACC_W) { + t_css.write_pending_hits += m_stats_pw.at(streamID)[type][status]; + } } - } - if (status == RESERVATION_FAIL) { - if (type == GLOBAL_ACC_R || type == CONST_ACC_R || type == INST_ACC_R) { - t_css.read_res_fails += m_stats_pw[type][status]; - } else if (type == GLOBAL_ACC_W) { - t_css.write_res_fails += m_stats_pw[type][status]; + if (status == RESERVATION_FAIL) { + if (type == GLOBAL_ACC_R || type == CONST_ACC_R || + type == INST_ACC_R) { + t_css.read_res_fails += m_stats_pw.at(streamID)[type][status]; + } else if (type == GLOBAL_ACC_W) { + t_css.write_res_fails += m_stats_pw.at(streamID)[type][status]; + } } } } @@ -1129,6 +1293,50 @@ void baseline_cache::display_state(FILE *fp) const { fprintf(fp, "\n"); } +void baseline_cache::inc_aggregated_stats(cache_request_status status, + cache_request_status cache_status, + mem_fetch *mf, + enum cache_gpu_level level) { + if (level == L1_GPU_CACHE) { + m_gpu->aggregated_l1_stats.inc_stats( + mf->get_streamID(), mf->get_access_type(), + m_gpu->aggregated_l1_stats.select_stats_status(status, cache_status)); + } else if (level == L2_GPU_CACHE) { + m_gpu->aggregated_l2_stats.inc_stats( + mf->get_streamID(), mf->get_access_type(), + m_gpu->aggregated_l2_stats.select_stats_status(status, cache_status)); + } +} + +void baseline_cache::inc_aggregated_fail_stats( + cache_request_status status, cache_request_status cache_status, + mem_fetch *mf, enum cache_gpu_level level) { + if (level == L1_GPU_CACHE) { + m_gpu->aggregated_l1_stats.inc_fail_stats( + mf->get_streamID(), mf->get_access_type(), + m_gpu->aggregated_l1_stats.select_stats_status(status, cache_status)); + } else if (level == L2_GPU_CACHE) { + m_gpu->aggregated_l2_stats.inc_fail_stats( + mf->get_streamID(), mf->get_access_type(), + m_gpu->aggregated_l2_stats.select_stats_status(status, cache_status)); + } +} + +void baseline_cache::inc_aggregated_stats_pw(cache_request_status status, + cache_request_status cache_status, + mem_fetch *mf, + enum cache_gpu_level level) { + if (level == L1_GPU_CACHE) { + m_gpu->aggregated_l1_stats.inc_stats_pw( + mf->get_streamID(), mf->get_access_type(), + m_gpu->aggregated_l1_stats.select_stats_status(status, cache_status)); + } else if (level == L2_GPU_CACHE) { + m_gpu->aggregated_l2_stats.inc_stats_pw( + mf->get_streamID(), mf->get_access_type(), + m_gpu->aggregated_l2_stats.select_stats_status(status, cache_status)); + } +} + /// Read miss handler without writeback void baseline_cache::send_read_request(new_addr_type addr, new_addr_type block_addr, @@ -1160,7 +1368,7 @@ void baseline_cache::send_read_request(new_addr_type addr, m_tag_array->access(block_addr, time, cache_index, wb, evicted, mf); m_mshrs.add(mshr_addr, mf); - m_stats.inc_stats(mf->get_access_type(), MSHR_HIT); + m_stats.inc_stats(mf->get_access_type(), MSHR_HIT, mf->get_streamID()); do_miss = true; } else if (!mshr_hit && mshr_avail && @@ -1181,9 +1389,11 @@ void baseline_cache::send_read_request(new_addr_type addr, do_miss = true; } else if (mshr_hit && !mshr_avail) - m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL); + m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL, + mf->get_streamID()); else if (!mshr_hit && !mshr_avail) - m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL); + m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL, + mf->get_streamID()); else assert(0); } @@ -1203,15 +1413,14 @@ void data_cache::update_m_readable(mem_fetch *mf, unsigned cache_index) { if (mf->get_access_sector_mask().test(i)) { bool all_set = true; for (unsigned k = i * SECTOR_SIZE; k < (i + 1) * SECTOR_SIZE; k++) { - // If any bit in the byte mask (within the sector) is not set, + // If any bit in the byte mask (within the sector) is not set, // the sector is unreadble if (!block->get_dirty_byte_mask().test(k)) { all_set = false; break; } } - if (all_set) - block->set_m_readable(true, mf->get_access_sector_mask()); + if (all_set) block->set_m_readable(true, mf->get_access_sector_mask()); } } } @@ -1232,7 +1441,7 @@ cache_request_status data_cache::wr_hit_wb(new_addr_type addr, } block->set_status(MODIFIED, mf->get_access_sector_mask()); block->set_byte_mask(mf); - update_m_readable(mf,cache_index); + update_m_readable(mf, cache_index); return HIT; } @@ -1244,7 +1453,8 @@ cache_request_status data_cache::wr_hit_wt(new_addr_type addr, std::list<cache_event> &events, enum cache_request_status status) { if (miss_queue_full(0)) { - m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); + m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL, + mf->get_streamID()); return RESERVATION_FAIL; // cannot handle request this cycle } @@ -1256,7 +1466,7 @@ cache_request_status data_cache::wr_hit_wt(new_addr_type addr, } block->set_status(MODIFIED, mf->get_access_sector_mask()); block->set_byte_mask(mf); - update_m_readable(mf,cache_index); + update_m_readable(mf, cache_index); // generate a write-through send_write_request(mf, cache_event(WRITE_REQUEST_SENT), time, events); @@ -1272,7 +1482,8 @@ cache_request_status data_cache::wr_hit_we(new_addr_type addr, std::list<cache_event> &events, enum cache_request_status status) { if (miss_queue_full(0)) { - m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); + m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL, + mf->get_streamID()); return RESERVATION_FAIL; // cannot handle request this cycle } @@ -1321,11 +1532,14 @@ enum cache_request_status data_cache::wr_miss_wa_naive( (m_miss_queue.size() < m_config.m_miss_queue_size)))) { // check what is the exactly the failure reason if (miss_queue_full(2)) - m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); + m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL, + mf->get_streamID()); else if (mshr_hit && !mshr_avail) - m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL); + m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL, + mf->get_streamID()); else if (!mshr_hit && !mshr_avail) - m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL); + m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL, + mf->get_streamID()); else assert(0); @@ -1344,10 +1558,10 @@ enum cache_request_status data_cache::wr_miss_wa_naive( mf->get_access_warp_mask(), mf->get_access_byte_mask(), mf->get_access_sector_mask(), m_gpu->gpgpu_ctx); - mem_fetch *n_mf = - new mem_fetch(*ma, NULL, mf->get_ctrl_size(), mf->get_wid(), - mf->get_sid(), mf->get_tpc(), mf->get_mem_config(), - m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle); + mem_fetch *n_mf = new mem_fetch( + *ma, NULL, mf->get_streamID(), mf->get_ctrl_size(), mf->get_wid(), + mf->get_sid(), mf->get_tpc(), mf->get_mem_config(), + m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle); bool do_miss = false; bool wb = false; @@ -1369,11 +1583,11 @@ enum cache_request_status data_cache::wr_miss_wa_naive( evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(), evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size, true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1, - NULL); + NULL, mf->get_streamID()); // the evicted block may have wrong chip id when advanced L2 hashing is // used, so set the right chip address from the original mf wb->set_chip(mf->get_tlx_addr().chip); - wb->set_parition(mf->get_tlx_addr().sub_partition); + wb->set_partition(mf->get_tlx_addr().sub_partition); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } @@ -1395,7 +1609,8 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write( // reserve mshr if (miss_queue_full(0)) { - m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); + m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL, + mf->get_streamID()); return RESERVATION_FAIL; // cannot handle request this cycle } @@ -1422,11 +1637,11 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write( evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(), evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size, true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1, - NULL); + NULL, mf->get_streamID()); // the evicted block may have wrong chip id when advanced L2 hashing is // used, so set the right chip address from the original mf wb->set_chip(mf->get_tlx_addr().chip); - wb->set_parition(mf->get_tlx_addr().sub_partition); + wb->set_partition(mf->get_tlx_addr().sub_partition); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } @@ -1442,11 +1657,14 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write( (m_miss_queue.size() < m_config.m_miss_queue_size)))) { // check what is the exactly the failure reason if (miss_queue_full(1)) - m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); + m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL, + mf->get_streamID()); else if (mshr_hit && !mshr_avail) - m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL); + m_stats.inc_fail_stats(mf->get_access_type(), MSHR_MERGE_ENRTY_FAIL, + mf->get_streamID()); else if (!mshr_hit && !mshr_avail) - m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL); + m_stats.inc_fail_stats(mf->get_access_type(), MSHR_ENRTY_FAIL, + mf->get_streamID()); else assert(0); @@ -1459,7 +1677,8 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write( if (m_mshrs.probe(mshr_addr) && m_mshrs.is_read_after_write_pending(mshr_addr) && mf->is_write()) { // assert(0); - m_stats.inc_fail_stats(mf->get_access_type(), MSHR_RW_PENDING); + m_stats.inc_fail_stats(mf->get_access_type(), MSHR_RW_PENDING, + mf->get_streamID()); return RESERVATION_FAIL; } @@ -1470,8 +1689,8 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write( mf->get_access_sector_mask(), m_gpu->gpgpu_ctx); mem_fetch *n_mf = new mem_fetch( - *ma, NULL, mf->get_ctrl_size(), mf->get_wid(), mf->get_sid(), - mf->get_tpc(), mf->get_mem_config(), + *ma, NULL, mf->get_streamID(), mf->get_ctrl_size(), mf->get_wid(), + mf->get_sid(), mf->get_tpc(), mf->get_mem_config(), m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, NULL, mf); new_addr_type block_addr = m_config.block_addr(addr); @@ -1495,11 +1714,11 @@ enum cache_request_status data_cache::wr_miss_wa_fetch_on_write( evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(), evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size, true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1, - NULL); + NULL, mf->get_streamID()); // the evicted block may have wrong chip id when advanced L2 hashing is // used, so set the right chip address from the original mf wb->set_chip(mf->get_tlx_addr().chip); - wb->set_parition(mf->get_tlx_addr().sub_partition); + wb->set_partition(mf->get_tlx_addr().sub_partition); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } @@ -1519,7 +1738,8 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read( // mshr if (miss_queue_full(0)) { - m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); + m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL, + mf->get_streamID()); return RESERVATION_FAIL; // cannot handle request this cycle } @@ -1552,7 +1772,7 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read( if (m_status == HIT_RESERVED) block->set_readable_on_fill(true, mf->get_access_sector_mask()); } - update_m_readable(mf,cache_index); + update_m_readable(mf, cache_index); if (m_status != RESERVATION_FAIL) { // If evicted block is modified and not a write-through @@ -1562,11 +1782,11 @@ enum cache_request_status data_cache::wr_miss_wa_lazy_fetch_on_read( evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(), evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size, true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1, - NULL); + NULL, mf->get_streamID()); // the evicted block may have wrong chip id when advanced L2 hashing is // used, so set the right chip address from the original mf wb->set_chip(mf->get_tlx_addr().chip); - wb->set_parition(mf->get_tlx_addr().sub_partition); + wb->set_partition(mf->get_tlx_addr().sub_partition); send_write_request(wb, cache_event(WRITE_BACK_REQUEST_SENT, evicted), time, events); } @@ -1580,7 +1800,8 @@ enum cache_request_status data_cache::wr_miss_no_wa( new_addr_type addr, unsigned cache_index, mem_fetch *mf, unsigned time, std::list<cache_event> &events, enum cache_request_status status) { if (miss_queue_full(0)) { - m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); + m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL, + mf->get_streamID()); return RESERVATION_FAIL; // cannot handle request this cycle } @@ -1625,7 +1846,8 @@ enum cache_request_status data_cache::rd_miss_base( if (miss_queue_full(1)) { // cannot handle request this cycle // (might need to generate two requests) - m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); + m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL, + mf->get_streamID()); return RESERVATION_FAIL; } @@ -1644,11 +1866,11 @@ enum cache_request_status data_cache::rd_miss_base( evicted.m_block_addr, m_wrbk_type, mf->get_access_warp_mask(), evicted.m_byte_mask, evicted.m_sector_mask, evicted.m_modified_size, true, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, -1, -1, -1, - NULL); + NULL, mf->get_streamID()); // the evicted block may have wrong chip id when advanced L2 hashing is // used, so set the right chip address from the original mf wb->set_chip(mf->get_tlx_addr().chip); - wb->set_parition(mf->get_tlx_addr().sub_partition); + wb->set_partition(mf->get_tlx_addr().sub_partition); send_write_request(wb, WRITE_BACK_REQUEST_SENT, time, events); } return MISS; @@ -1684,16 +1906,20 @@ enum cache_request_status read_only_cache::access( cache_status = RESERVATION_FAIL; } else { cache_status = RESERVATION_FAIL; - m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL); + m_stats.inc_fail_stats(mf->get_access_type(), MISS_QUEUE_FULL, + mf->get_streamID()); } } else { - m_stats.inc_fail_stats(mf->get_access_type(), LINE_ALLOC_FAIL); + m_stats.inc_fail_stats(mf->get_access_type(), LINE_ALLOC_FAIL, + mf->get_streamID()); } m_stats.inc_stats(mf->get_access_type(), - m_stats.select_stats_status(status, cache_status)); + m_stats.select_stats_status(status, cache_status), + mf->get_streamID()); m_stats.inc_stats_pw(mf->get_access_type(), - m_stats.select_stats_status(status, cache_status)); + m_stats.select_stats_status(status, cache_status), + mf->get_streamID()); return cache_status; } @@ -1721,7 +1947,8 @@ enum cache_request_status data_cache::process_tag_probe( } else { // the only reason for reservation fail here is LINE_ALLOC_FAIL (i.e all // lines are reserved) - m_stats.inc_fail_stats(mf->get_access_type(), LINE_ALLOC_FAIL); + m_stats.inc_fail_stats(mf->get_access_type(), LINE_ALLOC_FAIL, + mf->get_streamID()); } } else { // Read if (probe_status == HIT) { @@ -1733,7 +1960,8 @@ enum cache_request_status data_cache::process_tag_probe( } else { // the only reason for reservation fail here is LINE_ALLOC_FAIL (i.e all // lines are reserved) - m_stats.inc_fail_stats(mf->get_access_type(), LINE_ALLOC_FAIL); + m_stats.inc_fail_stats(mf->get_access_type(), LINE_ALLOC_FAIL, + mf->get_streamID()); } } @@ -1758,9 +1986,11 @@ enum cache_request_status data_cache::access(new_addr_type addr, mem_fetch *mf, enum cache_request_status access_status = process_tag_probe(wr, probe_status, addr, cache_index, mf, time, events); m_stats.inc_stats(mf->get_access_type(), - m_stats.select_stats_status(probe_status, access_status)); - m_stats.inc_stats_pw(mf->get_access_type(), m_stats.select_stats_status( - probe_status, access_status)); + m_stats.select_stats_status(probe_status, access_status), + mf->get_streamID()); + m_stats.inc_stats_pw(mf->get_access_type(), + m_stats.select_stats_status(probe_status, access_status), + mf->get_streamID()); return access_status; } @@ -1822,14 +2052,17 @@ enum cache_request_status tex_cache::access(new_addr_type addr, mem_fetch *mf, cache_status = HIT_RESERVED; } m_stats.inc_stats(mf->get_access_type(), - m_stats.select_stats_status(status, cache_status)); + m_stats.select_stats_status(status, cache_status), + mf->get_streamID()); m_stats.inc_stats_pw(mf->get_access_type(), - m_stats.select_stats_status(status, cache_status)); + m_stats.select_stats_status(status, cache_status), + mf->get_streamID()); return cache_status; } void tex_cache::cycle() { // send next request to lower level of memory + // TODO: Use different full() for sst_mem_interface? if (!m_request_fifo.empty()) { mem_fetch *mf = m_request_fifo.peek(); if (!m_memport->full(mf->get_ctrl_size(), false)) { diff --git a/src/gpgpu-sim/gpu-cache.h b/src/gpgpu-sim/gpu-cache.h index 498dfeb..c07695f 100644 --- a/src/gpgpu-sim/gpu-cache.h +++ b/src/gpgpu-sim/gpu-cache.h @@ -1,16 +1,18 @@ -// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University +// Copyright (c) 2009-2021, Tor M. Aamodt, Tayler Hetherington, Vijay Kandiah, +// Nikos Hardavellas, Mahmoud Khairy, Junrui Pan, Timothy G. Rogers The +// University of British Columbia, Northwestern University, Purdue University // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -70,6 +72,13 @@ enum cache_event_type { WRITE_ALLOCATE_SENT }; +enum cache_gpu_level { + L1_GPU_CACHE = 0, + L2_GPU_CACHE, + OTHER_GPU_CACHE, + NUM_CACHE_GPU_LEVELS +}; + struct evicted_block_info { new_addr_type m_block_addr; unsigned m_modified_size; @@ -498,6 +507,7 @@ struct sector_cache_block : public cache_block_t { for (unsigned i = 0; i < SECTOR_CHUNCK_SIZE; ++i) { if (sector_mask.to_ulong() & (1 << i)) return i; } + return SECTOR_CHUNCK_SIZE; // error } }; @@ -720,9 +730,16 @@ class cache_config { "Invalid cache configuration: FETCH_ON_WRITE and LAZY_FETCH_ON_READ " "cannot work properly with ON_FILL policy. Cache must be ON_MISS. "); } + if (m_cache_type == SECTOR) { - assert(m_line_sz / SECTOR_SIZE == SECTOR_CHUNCK_SIZE && - m_line_sz % SECTOR_SIZE == 0); + bool cond = m_line_sz / SECTOR_SIZE == SECTOR_CHUNCK_SIZE && + m_line_sz % SECTOR_SIZE == 0; + if (!cond) { + std::cerr << "error: For sector cache, the simulator uses hard-coded " + "SECTOR_SIZE and SECTOR_CHUNCK_SIZE. The line size " + "must be product of both values.\n"; + assert(0); + } } // default: port to data array width and granularity = line size @@ -1190,20 +1207,26 @@ class cache_stats { void clear(); // Clear AerialVision cache stats after each window void clear_pw(); - void inc_stats(int access_type, int access_outcome); + void inc_stats(int access_type, int access_outcome, + unsigned long long streamID); // Increment AerialVision cache stats - void inc_stats_pw(int access_type, int access_outcome); - void inc_fail_stats(int access_type, int fail_outcome); + void inc_stats_pw(int access_type, int access_outcome, + unsigned long long streamID); + void inc_fail_stats(int access_type, int fail_outcome, + unsigned long long streamID); enum cache_request_status select_stats_status( enum cache_request_status probe, enum cache_request_status access) const; unsigned long long &operator()(int access_type, int access_outcome, - bool fail_outcome); + bool fail_outcome, + unsigned long long streamID); unsigned long long operator()(int access_type, int access_outcome, - bool fail_outcome) const; + bool fail_outcome, + unsigned long long streamID) const; cache_stats operator+(const cache_stats &cs); cache_stats &operator+=(const cache_stats &cs); - void print_stats(FILE *fout, const char *cache_name = "Cache_stats") const; - void print_fail_stats(FILE *fout, + void print_stats(FILE *fout, unsigned long long streamID, + const char *cache_name = "Cache_stats") const; + void print_fail_stats(FILE *fout, unsigned long long streamID, const char *cache_name = "Cache_fail_stats") const; unsigned long long get_stats(enum mem_access_type *access_type, @@ -1221,10 +1244,14 @@ class cache_stats { bool check_valid(int type, int status) const; bool check_fail_valid(int type, int fail) const; - std::vector<std::vector<unsigned long long> > m_stats; + // CUDA streamID -> cache stats[NUM_MEM_ACCESS_TYPE] + std::map<unsigned long long, std::vector<std::vector<unsigned long long>>> + m_stats; // AerialVision cache stats (per-window) - std::vector<std::vector<unsigned long long> > m_stats_pw; - std::vector<std::vector<unsigned long long> > m_fail_stats; + std::map<unsigned long long, std::vector<std::vector<unsigned long long>>> + m_stats_pw; + std::map<unsigned long long, std::vector<std::vector<unsigned long long>>> + m_fail_stats; unsigned long long m_cache_port_available_cycles; unsigned long long m_cache_data_port_busy_cycles; @@ -1254,11 +1281,14 @@ class baseline_cache : public cache_t { public: baseline_cache(const char *name, cache_config &config, int core_id, int type_id, mem_fetch_interface *memport, - enum mem_fetch_status status) + enum mem_fetch_status status, enum cache_gpu_level level, + gpgpu_sim *gpu) : m_config(config), m_tag_array(new tag_array(config, core_id, type_id)), m_mshrs(config.m_mshr_entries, config.m_mshr_max_merge), - m_bandwidth_management(config) { + m_bandwidth_management(config), + m_level(level), + m_gpu(gpu) { init(name, config, memport, status); } @@ -1326,6 +1356,15 @@ class baseline_cache : public cache_t { bool fill_port_free() const { return m_bandwidth_management.fill_port_free(); } + void inc_aggregated_stats(cache_request_status status, + cache_request_status cache_status, mem_fetch *mf, + enum cache_gpu_level level); + void inc_aggregated_fail_stats(cache_request_status status, + cache_request_status cache_status, + mem_fetch *mf, enum cache_gpu_level level); + void inc_aggregated_stats_pw(cache_request_status status, + cache_request_status cache_status, mem_fetch *mf, + enum cache_gpu_level level); // This is a gapping hole we are poking in the system to quickly handle // filling the cache on cudamemcopies. We don't care about anything other than @@ -1357,6 +1396,8 @@ class baseline_cache : public cache_t { std::list<mem_fetch *> m_miss_queue; enum mem_fetch_status m_miss_queue_status; mem_fetch_interface *m_memport; + cache_gpu_level m_level; + gpgpu_sim *m_gpu; struct extra_mf_fields { extra_mf_fields() { m_valid = false; } @@ -1443,8 +1484,10 @@ class read_only_cache : public baseline_cache { public: read_only_cache(const char *name, cache_config &config, int core_id, int type_id, mem_fetch_interface *memport, - enum mem_fetch_status status) - : baseline_cache(name, config, core_id, type_id, memport, status) {} + enum mem_fetch_status status, enum cache_gpu_level level, + gpgpu_sim *gpu) + : baseline_cache(name, config, core_id, type_id, memport, status, level, + gpu) {} /// Access cache for read_only_cache: returns RESERVATION_FAIL if request /// could not be accepted (for any reason) @@ -1468,8 +1511,10 @@ class data_cache : public baseline_cache { data_cache(const char *name, cache_config &config, int core_id, int type_id, mem_fetch_interface *memport, mem_fetch_allocator *mfcreator, enum mem_fetch_status status, mem_access_type wr_alloc_type, - mem_access_type wrbk_type, class gpgpu_sim *gpu) - : baseline_cache(name, config, core_id, type_id, memport, status) { + mem_access_type wrbk_type, class gpgpu_sim *gpu, + enum cache_gpu_level level) + : baseline_cache(name, config, core_id, type_id, memport, status, level, + gpu) { init(mfcreator); m_wr_alloc_type = wr_alloc_type; m_wrbk_type = wrbk_type; @@ -1658,9 +1703,10 @@ class l1_cache : public data_cache { public: l1_cache(const char *name, cache_config &config, int core_id, int type_id, mem_fetch_interface *memport, mem_fetch_allocator *mfcreator, - enum mem_fetch_status status, class gpgpu_sim *gpu) + enum mem_fetch_status status, class gpgpu_sim *gpu, + enum cache_gpu_level level) : data_cache(name, config, core_id, type_id, memport, mfcreator, status, - L1_WR_ALLOC_R, L1_WRBK_ACC, gpu) {} + L1_WR_ALLOC_R, L1_WRBK_ACC, gpu, level) {} virtual ~l1_cache() {} @@ -1683,9 +1729,10 @@ class l2_cache : public data_cache { public: l2_cache(const char *name, cache_config &config, int core_id, int type_id, mem_fetch_interface *memport, mem_fetch_allocator *mfcreator, - enum mem_fetch_status status, class gpgpu_sim *gpu) + enum mem_fetch_status status, class gpgpu_sim *gpu, + enum cache_gpu_level level) : data_cache(name, config, core_id, type_id, memport, mfcreator, status, - L2_WR_ALLOC_R, L2_WRBK_ACC, gpu) {} + L2_WR_ALLOC_R, L2_WRBK_ACC, gpu, level) {} virtual ~l2_cache() {} diff --git a/src/gpgpu-sim/gpu-sim.cc b/src/gpgpu-sim/gpu-sim.cc index e44551e..55d70d1 100644 --- a/src/gpgpu-sim/gpu-sim.cc +++ b/src/gpgpu-sim/gpu-sim.cc @@ -1,17 +1,19 @@ // Copyright (c) 2009-2021, Tor M. Aamodt, Wilson W.L. Fung, George L. Yuan, -// Ali Bakhoda, Andrew Turner, Ivan Sham, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// Ali Bakhoda, Andrew Turner, Ivan Sham, Vijay Kandiah, Nikos Hardavellas, +// Mahmoud Khairy, Junrui Pan, Timothy G. Rogers +// The University of British Columbia, Northwestern University, Purdue +// University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -79,7 +81,7 @@ class gpgpu_sim_wrapper {}; #include <sstream> #include <string> -#define MAX(a, b) (((a) > (b)) ? (a) : (b)) +// #define MAX(a, b) (((a) > (b)) ? (a) : (b)) //redefined bool g_interactive_debugger_enabled = false; @@ -96,7 +98,6 @@ tr1_hash_map<new_addr_type, unsigned> address_random_interleaving; #include "mem_latency_stat.h" - void power_config::reg_options(class OptionParser *opp) { option_parser_register(opp, "-accelwattch_xml_file", OPT_CSTR, &g_power_config_name, "AccelWattch XML file", @@ -110,91 +111,106 @@ void power_config::reg_options(class OptionParser *opp) { &g_power_per_cycle_dump, "Dump detailed power output each cycle", "0"); - - - option_parser_register(opp, "-hw_perf_file_name", OPT_CSTR, - &g_hw_perf_file_name, "Hardware Performance Statistics file", - "hw_perf.csv"); + &g_hw_perf_file_name, + "Hardware Performance Statistics file", "hw_perf.csv"); - option_parser_register(opp, "-hw_perf_bench_name", OPT_CSTR, - &g_hw_perf_bench_name, "Kernel Name in Hardware Performance Statistics file", - ""); + option_parser_register( + opp, "-hw_perf_bench_name", OPT_CSTR, &g_hw_perf_bench_name, + "Kernel Name in Hardware Performance Statistics file", ""); option_parser_register(opp, "-power_simulation_mode", OPT_INT32, &g_power_simulation_mode, - "Switch performance counter input for power simulation (0=Sim, 1=HW, 2=HW-Sim Hybrid)", "0"); + "Switch performance counter input for power " + "simulation (0=Sim, 1=HW, 2=HW-Sim Hybrid)", + "0"); - option_parser_register(opp, "-dvfs_enabled", OPT_BOOL, - &g_dvfs_enabled, + option_parser_register(opp, "-dvfs_enabled", OPT_BOOL, &g_dvfs_enabled, "Turn on DVFS for power model", "0"); option_parser_register(opp, "-aggregate_power_stats", OPT_BOOL, &g_aggregate_power_stats, "Accumulate power across all kernels", "0"); - //Accelwattch Hyrbid Configuration + // Accelwattch Hyrbid Configuration - option_parser_register(opp, "-accelwattch_hybrid_perfsim_L1_RH", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_L1_RH], - "Get L1 Read Hits for Accelwattch-Hybrid from Accel-Sim", "0"); - option_parser_register(opp, "-accelwattch_hybrid_perfsim_L1_RM", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_L1_RM], - "Get L1 Read Misses for Accelwattch-Hybrid from Accel-Sim", "0"); - option_parser_register(opp, "-accelwattch_hybrid_perfsim_L1_WH", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_L1_WH], - "Get L1 Write Hits for Accelwattch-Hybrid from Accel-Sim", "0"); - option_parser_register(opp, "-accelwattch_hybrid_perfsim_L1_WM", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_L1_WM], - "Get L1 Write Misses for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_L1_RH", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_L1_RH], + "Get L1 Read Hits for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_L1_RM", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_L1_RM], + "Get L1 Read Misses for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_L1_WH", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_L1_WH], + "Get L1 Write Hits for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_L1_WM", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_L1_WM], + "Get L1 Write Misses for Accelwattch-Hybrid from Accel-Sim", "0"); - option_parser_register(opp, "-accelwattch_hybrid_perfsim_L2_RH", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_L2_RH], - "Get L2 Read Hits for Accelwattch-Hybrid from Accel-Sim", "0"); - option_parser_register(opp, "-accelwattch_hybrid_perfsim_L2_RM", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_L2_RM], - "Get L2 Read Misses for Accelwattch-Hybrid from Accel-Sim", "0"); - option_parser_register(opp, "-accelwattch_hybrid_perfsim_L2_WH", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_L2_WH], - "Get L2 Write Hits for Accelwattch-Hybrid from Accel-Sim", "0"); - option_parser_register(opp, "-accelwattch_hybrid_perfsim_L2_WM", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_L2_WM], - "Get L2 Write Misses for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_L2_RH", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_L2_RH], + "Get L2 Read Hits for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_L2_RM", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_L2_RM], + "Get L2 Read Misses for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_L2_WH", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_L2_WH], + "Get L2 Write Hits for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_L2_WM", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_L2_WM], + "Get L2 Write Misses for Accelwattch-Hybrid from Accel-Sim", "0"); - option_parser_register(opp, "-accelwattch_hybrid_perfsim_CC_ACC", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_CC_ACC], - "Get Constant Cache Acesses for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_CC_ACC", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_CC_ACC], + "Get Constant Cache Acesses for Accelwattch-Hybrid from Accel-Sim", "0"); - option_parser_register(opp, "-accelwattch_hybrid_perfsim_SHARED_ACC", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_SHRD_ACC], - "Get Shared Memory Acesses for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_SHARED_ACC", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_SHRD_ACC], + "Get Shared Memory Acesses for Accelwattch-Hybrid from Accel-Sim", "0"); option_parser_register(opp, "-accelwattch_hybrid_perfsim_DRAM_RD", OPT_BOOL, &accelwattch_hybrid_configuration[HW_DRAM_RD], - "Get DRAM Reads for Accelwattch-Hybrid from Accel-Sim", "0"); - option_parser_register(opp, "-accelwattch_hybrid_perfsim_DRAM_WR", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_DRAM_WR], - "Get DRAM Writes for Accelwattch-Hybrid from Accel-Sim", "0"); - - option_parser_register(opp, "-accelwattch_hybrid_perfsim_NOC", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_NOC], - "Get Interconnect Acesses for Accelwattch-Hybrid from Accel-Sim", "0"); + "Get DRAM Reads for Accelwattch-Hybrid from Accel-Sim", + "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_DRAM_WR", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_DRAM_WR], + "Get DRAM Writes for Accelwattch-Hybrid from Accel-Sim", "0"); - option_parser_register(opp, "-accelwattch_hybrid_perfsim_PIPE_DUTY", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_PIPE_DUTY], - "Get Pipeline Duty Cycle Acesses for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_NOC", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_NOC], + "Get Interconnect Acesses for Accelwattch-Hybrid from Accel-Sim", "0"); - option_parser_register(opp, "-accelwattch_hybrid_perfsim_NUM_SM_IDLE", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_NUM_SM_IDLE], - "Get Number of Idle SMs for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_PIPE_DUTY", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_PIPE_DUTY], + "Get Pipeline Duty Cycle Acesses for Accelwattch-Hybrid from Accel-Sim", + "0"); - option_parser_register(opp, "-accelwattch_hybrid_perfsim_CYCLES", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_CYCLES], - "Get Executed Cycles for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_NUM_SM_IDLE", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_NUM_SM_IDLE], + "Get Number of Idle SMs for Accelwattch-Hybrid from Accel-Sim", "0"); - option_parser_register(opp, "-accelwattch_hybrid_perfsim_VOLTAGE", OPT_BOOL, - &accelwattch_hybrid_configuration[HW_VOLTAGE], - "Get Chip Voltage for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_CYCLES", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_CYCLES], + "Get Executed Cycles for Accelwattch-Hybrid from Accel-Sim", "0"); + option_parser_register( + opp, "-accelwattch_hybrid_perfsim_VOLTAGE", OPT_BOOL, + &accelwattch_hybrid_configuration[HW_VOLTAGE], + "Get Chip Voltage for Accelwattch-Hybrid from Accel-Sim", "0"); // Output Data Formats option_parser_register( @@ -303,6 +319,9 @@ void memory_config::reg_options(class OptionParser *opp) { "elimnate_rw_turnaround i.e set tWTR and tRTW = 0", "0"); option_parser_register(opp, "-icnt_flit_size", OPT_UINT32, &icnt_flit_size, "icnt_flit_size", "32"); + // SST mode activate + option_parser_register(opp, "-SST_mode", OPT_BOOL, &SST_mode, "SST mode", + "0"); m_address_mapping.addrdec_setoption(opp); } @@ -394,7 +413,7 @@ void shader_core_config::reg_options(class OptionParser *opp) { "gpgpu_ignore_resources_limitation (default 0)", "0"); option_parser_register( opp, "-gpgpu_shader_cta", OPT_UINT32, &max_cta_per_core, - "Maximum number of concurrent CTAs in shader (default 8)", "8"); + "Maximum number of concurrent CTAs in shader (default 32)", "32"); option_parser_register( opp, "-gpgpu_num_cta_barriers", OPT_UINT32, &max_barriers_per_cta, "Maximum number of named barriers per CTA (default 16)", "16"); @@ -585,26 +604,26 @@ void shader_core_config::reg_options(class OptionParser *opp) { "ID_OC_SP,ID_OC_DP,ID_OC_INT,ID_OC_SFU,ID_OC_MEM,OC_EX_SP,OC_EX_DP,OC_EX_" "INT,OC_EX_SFU,OC_EX_MEM,EX_WB,ID_OC_TENSOR_CORE,OC_EX_TENSOR_CORE", "1,1,1,1,1,1,1,1,1,1,1,1,1"); - option_parser_register(opp, "-gpgpu_tensor_core_avail", OPT_INT32, + option_parser_register(opp, "-gpgpu_tensor_core_avail", OPT_UINT32, &gpgpu_tensor_core_avail, "Tensor Core Available (default=0)", "0"); - option_parser_register(opp, "-gpgpu_num_sp_units", OPT_INT32, + option_parser_register(opp, "-gpgpu_num_sp_units", OPT_UINT32, &gpgpu_num_sp_units, "Number of SP units (default=1)", "1"); - option_parser_register(opp, "-gpgpu_num_dp_units", OPT_INT32, + option_parser_register(opp, "-gpgpu_num_dp_units", OPT_UINT32, &gpgpu_num_dp_units, "Number of DP units (default=0)", "0"); - option_parser_register(opp, "-gpgpu_num_int_units", OPT_INT32, + option_parser_register(opp, "-gpgpu_num_int_units", OPT_UINT32, &gpgpu_num_int_units, "Number of INT units (default=0)", "0"); - option_parser_register(opp, "-gpgpu_num_sfu_units", OPT_INT32, + option_parser_register(opp, "-gpgpu_num_sfu_units", OPT_UINT32, &gpgpu_num_sfu_units, "Number of SF units (default=1)", "1"); - option_parser_register(opp, "-gpgpu_num_tensor_core_units", OPT_INT32, + option_parser_register(opp, "-gpgpu_num_tensor_core_units", OPT_UINT32, &gpgpu_num_tensor_core_units, "Number of tensor_core units (default=1)", "0"); option_parser_register( - opp, "-gpgpu_num_mem_units", OPT_INT32, &gpgpu_num_mem_units, + opp, "-gpgpu_num_mem_units", OPT_UINT32, &gpgpu_num_mem_units, "Number if ldst units (default=1) WARNING: not hooked up to anything", "1"); option_parser_register( @@ -700,7 +719,9 @@ void gpgpu_sim_config::reg_options(option_parser_t opp) { "500.0:2000.0:2000.0:2000.0"); option_parser_register( opp, "-gpgpu_max_concurrent_kernel", OPT_INT32, &max_concurrent_kernel, - "maximum kernels that can run concurrently on GPU", "8"); + "maximum kernels that can run concurrently on GPU, set this value " + "according to max resident grids for your compute capability", + "32"); option_parser_register( opp, "-gpgpu_cflog_interval", OPT_INT32, &gpgpu_cflog_interval, "Interval between each snapshot in control flow logger", "0"); @@ -770,6 +791,22 @@ void increment_x_then_y_then_z(dim3 &i, const dim3 &bound) { } void gpgpu_sim::launch(kernel_info_t *kinfo) { + unsigned kernelID = kinfo->get_uid(); + unsigned long long streamID = kinfo->get_streamID(); + + kernel_time_t kernel_time = {gpu_tot_sim_cycle + gpu_sim_cycle, 0}; + if (gpu_kernel_time.find(streamID) == gpu_kernel_time.end()) { + std::map<unsigned, kernel_time_t> new_val; + new_val.insert(std::pair<unsigned, kernel_time_t>(kernelID, kernel_time)); + gpu_kernel_time.insert( + std::pair<unsigned long long, std::map<unsigned, kernel_time_t>>( + streamID, new_val)); + } else { + gpu_kernel_time.at(streamID).insert( + std::pair<unsigned, kernel_time_t>(kernelID, kernel_time)); + ////////// assume same kernel ID do not appear more than once + } + unsigned cta_size = kinfo->threads_per_cta(); if (cta_size > m_shader_config->n_thread_per_shader) { printf( @@ -875,7 +912,10 @@ kernel_info_t *gpgpu_sim::select_kernel() { } unsigned gpgpu_sim::finished_kernel() { - if (m_finished_kernel.empty()) return 0; + if (m_finished_kernel.empty()) { + last_streamID = -1; + return 0; + } unsigned result = m_finished_kernel.front(); m_finished_kernel.pop_front(); return result; @@ -883,6 +923,11 @@ unsigned gpgpu_sim::finished_kernel() { void gpgpu_sim::set_kernel_done(kernel_info_t *kernel) { unsigned uid = kernel->get_uid(); + last_uid = uid; + unsigned long long streamID = kernel->get_streamID(); + last_streamID = streamID; + gpu_kernel_time.at(streamID).at(uid).end_cycle = + gpu_tot_sim_cycle + gpu_sim_cycle; m_finished_kernel.push_back(uid); std::vector<kernel_info_t *>::iterator k; for (k = m_running_kernels.begin(); k != m_running_kernels.end(); k++) { @@ -913,6 +958,16 @@ void exec_gpgpu_sim::createSIMTCluster() { m_shader_stats, m_memory_stats); } +// SST get its own simt_cluster +void sst_gpgpu_sim::createSIMTCluster() { + m_cluster = new simt_core_cluster *[m_shader_config->n_simt_clusters]; + for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++) + m_cluster[i] = + new sst_simt_core_cluster(this, i, m_shader_config, m_memory_config, + m_shader_stats, m_memory_stats); + SST_gpgpu_reply_buffer.resize(m_shader_config->n_simt_clusters); +} + gpgpu_sim::gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx) : gpgpu_t(config, ctx), m_config(config) { gpgpu_ctx = ctx; @@ -922,8 +977,9 @@ gpgpu_sim::gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx) ptx_file_line_stats_create_exposed_latency_tracker(m_config.num_shader()); #ifdef GPGPUSIM_POWER_MODEL - m_gpgpusim_wrapper = new gpgpu_sim_wrapper(config.g_power_simulation_enabled, - config.g_power_config_name, config.g_power_simulation_mode, config.g_dvfs_enabled); + m_gpgpusim_wrapper = new gpgpu_sim_wrapper( + config.g_power_simulation_enabled, config.g_power_config_name, + config.g_power_simulation_mode, config.g_dvfs_enabled); #endif m_shader_stats = new shader_core_stats(m_shader_config); @@ -952,27 +1008,33 @@ gpgpu_sim::gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx) gpu_tot_sim_cycle_parition_util = 0; partiton_replys_in_parallel = 0; partiton_replys_in_parallel_total = 0; + last_streamID = -1; - m_memory_partition_unit = - new memory_partition_unit *[m_memory_config->m_n_mem]; - m_memory_sub_partition = - new memory_sub_partition *[m_memory_config->m_n_mem_sub_partition]; - for (unsigned i = 0; i < m_memory_config->m_n_mem; i++) { - m_memory_partition_unit[i] = - new memory_partition_unit(i, m_memory_config, m_memory_stats, this); - for (unsigned p = 0; - p < m_memory_config->m_n_sub_partition_per_memory_channel; p++) { - unsigned submpid = - i * m_memory_config->m_n_sub_partition_per_memory_channel + p; - m_memory_sub_partition[submpid] = - m_memory_partition_unit[i]->get_sub_partition(p); - } - } + gpu_kernel_time.clear(); - icnt_wrapper_init(); - icnt_create(m_shader_config->n_simt_clusters, - m_memory_config->m_n_mem_sub_partition); + // TODO: somehow move this logic to the sst_gpgpu_sim constructor? + if (!m_config.is_SST_mode()) { + // Init memory if not in SST mode + m_memory_partition_unit = + new memory_partition_unit *[m_memory_config->m_n_mem]; + m_memory_sub_partition = + new memory_sub_partition *[m_memory_config->m_n_mem_sub_partition]; + for (unsigned i = 0; i < m_memory_config->m_n_mem; i++) { + m_memory_partition_unit[i] = + new memory_partition_unit(i, m_memory_config, m_memory_stats, this); + for (unsigned p = 0; + p < m_memory_config->m_n_sub_partition_per_memory_channel; p++) { + unsigned submpid = + i * m_memory_config->m_n_sub_partition_per_memory_channel + p; + m_memory_sub_partition[submpid] = + m_memory_partition_unit[i]->get_sub_partition(p); + } + } + icnt_wrapper_init(); + icnt_create(m_shader_config->n_simt_clusters, + m_memory_config->m_n_mem_sub_partition); + } time_vector_create(NUM_MEM_REQ_STAT); fprintf(stdout, "GPGPU-Sim uArch: performance model initialization complete.\n"); @@ -991,6 +1053,22 @@ gpgpu_sim::gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx) m_functional_sim_kernel = NULL; } +void sst_gpgpu_sim::SST_receive_mem_reply(unsigned core_id, void *mem_req) { + assert(core_id < m_shader_config->n_simt_clusters); + mem_fetch *mf = (mem_fetch *)mem_req; + + (SST_gpgpu_reply_buffer[core_id]).push_back(mf); +} + +mem_fetch *sst_gpgpu_sim::SST_pop_mem_reply(unsigned core_id) { + if (SST_gpgpu_reply_buffer[core_id].size() > 0) { + mem_fetch *temp = SST_gpgpu_reply_buffer[core_id].front(); + SST_gpgpu_reply_buffer[core_id].pop_front(); + return temp; + } else + return NULL; +} + int gpgpu_sim::shared_mem_size() const { return m_shader_config->gpgpu_shmem_size; } @@ -1086,6 +1164,26 @@ bool gpgpu_sim::active() { return false; } +bool sst_gpgpu_sim::active() { + if (m_config.gpu_max_cycle_opt && + (gpu_tot_sim_cycle + gpu_sim_cycle) >= m_config.gpu_max_cycle_opt) + return false; + if (m_config.gpu_max_insn_opt && + (gpu_tot_sim_insn + gpu_sim_insn) >= m_config.gpu_max_insn_opt) + return false; + if (m_config.gpu_max_cta_opt && + (gpu_tot_issued_cta >= m_config.gpu_max_cta_opt)) + return false; + if (m_config.gpu_max_completed_cta_opt && + (gpu_completed_cta >= m_config.gpu_max_completed_cta_opt)) + return false; + if (m_config.gpu_deadlock_detect && gpu_deadlock) return false; + for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++) + if (m_cluster[i]->get_not_completed() > 0) return true; + if (get_more_cta_left()) return true; + return false; +} + void gpgpu_sim::init() { // run a CUDA grid on the GPU microarchitecture simulator gpu_sim_cycle = 0; @@ -1155,14 +1253,13 @@ void gpgpu_sim::update_stats() { gpu_occupancy = occupancy_stats(); } -PowerscalingCoefficients *gpgpu_sim::get_scaling_coeffs() -{ +PowerscalingCoefficients *gpgpu_sim::get_scaling_coeffs() { return m_gpgpusim_wrapper->get_scaling_coeffs(); } -void gpgpu_sim::print_stats() { +void gpgpu_sim::print_stats(unsigned long long streamID) { gpgpu_ctx->stats->ptx_file_line_stats_write_file(); - gpu_print_stat(); + gpu_print_stat(streamID); if (g_network_mode) { printf( @@ -1241,10 +1338,10 @@ std::string gpgpu_sim::executed_kernel_info_string() { } std::string gpgpu_sim::executed_kernel_name() { - std::stringstream statout; - if( m_executed_kernel_names.size() == 1) - statout << m_executed_kernel_names[0]; - else{ + std::stringstream statout; + if (m_executed_kernel_names.size() == 1) + statout << m_executed_kernel_names[0]; + else { for (unsigned int k = 0; k < m_executed_kernel_names.size(); k++) { statout << m_executed_kernel_names[k] << " "; } @@ -1345,12 +1442,15 @@ void gpgpu_sim::clear_executed_kernel_info() { m_executed_kernel_names.clear(); m_executed_kernel_uids.clear(); } -void gpgpu_sim::gpu_print_stat() { + +void gpgpu_sim::gpu_print_stat(unsigned long long streamID) { FILE *statfout = stdout; std::string kernel_info_str = executed_kernel_info_string(); fprintf(statfout, "%s", kernel_info_str.c_str()); + printf("kernel_stream_id = %llu\n", streamID); + printf("gpu_sim_cycle = %lld\n", gpu_sim_cycle); printf("gpu_sim_insn = %lld\n", gpu_sim_insn); printf("gpu_ipc = %12.4f\n", (float)gpu_sim_insn / gpu_sim_cycle); @@ -1397,13 +1497,13 @@ void gpgpu_sim::gpu_print_stat() { // %lld\n", partiton_replys_in_parallel_total ); printf("L2_BW = %12.4f GB/Sec\n", ((float)(partiton_replys_in_parallel * 32) / - (gpu_sim_cycle * m_config.icnt_period)) / + (gpu_sim_cycle * m_config.core_period)) / 1000000000); printf("L2_BW_total = %12.4f GB/Sec\n", ((float)((partiton_replys_in_parallel + partiton_replys_in_parallel_total) * 32) / - ((gpu_tot_sim_cycle + gpu_sim_cycle) * m_config.icnt_period)) / + ((gpu_tot_sim_cycle + gpu_sim_cycle) * m_config.core_period)) / 1000000000); time_t curr_time; @@ -1422,29 +1522,33 @@ void gpgpu_sim::gpu_print_stat() { m_cluster[i]->get_cache_stats(core_cache_stats); } printf("\nTotal_core_cache_stats:\n"); - core_cache_stats.print_stats(stdout, "Total_core_cache_stats_breakdown"); + core_cache_stats.print_stats(stdout, streamID, + "Total_core_cache_stats_breakdown"); printf("\nTotal_core_cache_fail_stats:\n"); - core_cache_stats.print_fail_stats(stdout, + core_cache_stats.print_fail_stats(stdout, streamID, "Total_core_cache_fail_stats_breakdown"); shader_print_scheduler_stat(stdout, false); m_shader_stats->print(stdout); #ifdef GPGPUSIM_POWER_MODEL if (m_config.g_power_simulation_enabled) { - if(m_config.g_power_simulation_mode > 0){ - //if(!m_config.g_aggregate_power_stats) - mcpat_reset_perf_count(m_gpgpusim_wrapper); - calculate_hw_mcpat(m_config, getShaderCoreConfig(), m_gpgpusim_wrapper, - m_power_stats, m_config.gpu_stat_sample_freq, - gpu_tot_sim_cycle, gpu_sim_cycle, gpu_tot_sim_insn, - gpu_sim_insn, m_config.g_power_simulation_mode, m_config.g_dvfs_enabled, - m_config.g_hw_perf_file_name, m_config.g_hw_perf_bench_name, executed_kernel_name(), m_config.accelwattch_hybrid_configuration, m_config.g_aggregate_power_stats); + if (m_config.g_power_simulation_mode > 0) { + // if(!m_config.g_aggregate_power_stats) + mcpat_reset_perf_count(m_gpgpusim_wrapper); + calculate_hw_mcpat(m_config, getShaderCoreConfig(), m_gpgpusim_wrapper, + m_power_stats, m_config.gpu_stat_sample_freq, + gpu_tot_sim_cycle, gpu_sim_cycle, gpu_tot_sim_insn, + gpu_sim_insn, m_config.g_power_simulation_mode, + m_config.g_dvfs_enabled, m_config.g_hw_perf_file_name, + m_config.g_hw_perf_bench_name, executed_kernel_name(), + m_config.accelwattch_hybrid_configuration, + m_config.g_aggregate_power_stats); } m_gpgpusim_wrapper->print_power_kernel_stats( gpu_sim_cycle, gpu_tot_sim_cycle, gpu_tot_sim_insn + gpu_sim_insn, kernel_info_str, true); - //if(!m_config.g_aggregate_power_stats) - mcpat_reset_perf_count(m_gpgpusim_wrapper); + // if(!m_config.g_aggregate_power_stats) + mcpat_reset_perf_count(m_gpgpusim_wrapper); } #endif @@ -1489,9 +1593,10 @@ void gpgpu_sim::gpu_print_stat() { printf("L2_total_cache_reservation_fails = %llu\n", total_l2_css.res_fails); printf("L2_total_cache_breakdown:\n"); - l2_stats.print_stats(stdout, "L2_cache_stats_breakdown"); + l2_stats.print_stats(stdout, streamID, "L2_cache_stats_breakdown"); printf("L2_total_cache_reservation_fail_breakdown:\n"); - l2_stats.print_fail_stats(stdout, "L2_cache_stats_fail_breakdown"); + l2_stats.print_fail_stats(stdout, streamID, + "L2_cache_stats_fail_breakdown"); total_l2_css.print_port_stats(stdout, "L2_cache"); } } @@ -1638,9 +1743,9 @@ bool shader_core_ctx::occupy_shader_resource_1block(kernel_info_t &k, SHADER_DPRINTF(LIVENESS, "GPGPU-Sim uArch: Occupied %u threads, %u shared mem, %u " - "registers, %u ctas\n", + "registers, %u ctas, on shader %d\n", m_occupied_n_threads, m_occupied_shmem, m_occupied_regs, - m_occupied_ctas); + m_occupied_ctas, m_sid); } return true; @@ -1806,9 +1911,10 @@ void shader_core_ctx::issue_block2core(kernel_info_t &kernel) { shader_CTA_count_log(m_sid, 1); SHADER_DPRINTF(LIVENESS, "GPGPU-Sim uArch: cta:%2u, start_tid:%4u, end_tid:%4u, " - "initialized @(%lld,%lld)\n", + "initialized @(%lld,%lld), kernel_uid:%u, kernel_name:%s\n", free_cta_hw_id, start_thread, end_thread, m_gpu->gpu_sim_cycle, - m_gpu->gpu_tot_sim_cycle); + m_gpu->gpu_tot_sim_cycle, kernel.get_uid(), + kernel.get_name().c_str()); } /////////////////////////////////////////////////////////////////////////////////////////// @@ -1933,8 +2039,10 @@ void gpgpu_sim::cycle() { if (mf) partiton_reqs_in_parallel_per_cycle++; } m_memory_sub_partition[i]->cache_cycle(gpu_sim_cycle + gpu_tot_sim_cycle); - m_memory_sub_partition[i]->accumulate_L2cache_stats( - m_power_stats->pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX]); + if (m_config.g_power_simulation_enabled) { + m_memory_sub_partition[i]->accumulate_L2cache_stats( + m_power_stats->pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX]); + } } } partiton_reqs_in_parallel += partiton_reqs_in_parallel_per_cycle; @@ -1956,11 +2064,13 @@ void gpgpu_sim::cycle() { *active_sms += m_cluster[i]->get_n_active_sms(); } // Update core icnt/cache stats for AccelWattch - m_cluster[i]->get_icnt_stats( - m_power_stats->pwr_mem_stat->n_simt_to_mem[CURRENT_STAT_IDX][i], - m_power_stats->pwr_mem_stat->n_mem_to_simt[CURRENT_STAT_IDX][i]); - m_cluster[i]->get_cache_stats( - m_power_stats->pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX]); + if (m_config.g_power_simulation_enabled) { + m_cluster[i]->get_icnt_stats( + m_power_stats->pwr_mem_stat->n_simt_to_mem[CURRENT_STAT_IDX][i], + m_power_stats->pwr_mem_stat->n_mem_to_simt[CURRENT_STAT_IDX][i]); + m_cluster[i]->get_cache_stats( + m_power_stats->pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX]); + } m_cluster[i]->get_current_occupancy( gpu_occupancy.aggregate_warp_slot_filled, gpu_occupancy.aggregate_theoretical_warp_slots); @@ -1985,11 +2095,11 @@ void gpgpu_sim::cycle() { // McPAT main cycle (interface with McPAT) #ifdef GPGPUSIM_POWER_MODEL if (m_config.g_power_simulation_enabled) { - if(m_config.g_power_simulation_mode == 0){ - mcpat_cycle(m_config, getShaderCoreConfig(), m_gpgpusim_wrapper, - m_power_stats, m_config.gpu_stat_sample_freq, - gpu_tot_sim_cycle, gpu_sim_cycle, gpu_tot_sim_insn, - gpu_sim_insn, m_config.g_dvfs_enabled); + if (m_config.g_power_simulation_mode == 0) { + mcpat_cycle(m_config, getShaderCoreConfig(), m_gpgpusim_wrapper, + m_power_stats, m_config.gpu_stat_sample_freq, + gpu_tot_sim_cycle, gpu_sim_cycle, gpu_tot_sim_insn, + gpu_sim_insn, m_config.g_dvfs_enabled); } } #endif @@ -2051,7 +2161,7 @@ void gpgpu_sim::cycle() { m_cluster[i]->get_current_occupancy(active, total); } DPRINTFG(LIVENESS, - "uArch: inst.: %lld (ipc=%4.1f, occ=%0.4f\% [%llu / %llu]) " + "uArch: inst.: %lld (ipc=%4.1f, occ=%0.4f%% [%llu / %llu]) " "sim_rate=%u (inst/sec) elapsed = %u:%u:%02u:%02u / %s", gpu_tot_sim_insn + gpu_sim_insn, (double)gpu_sim_insn / (double)gpu_sim_cycle, @@ -2099,6 +2209,11 @@ void gpgpu_sim::cycle() { } } +void sst_gpgpu_sim::cycle() { + SST_cycle(); + return; +} + void shader_core_ctx::dump_warp_state(FILE *fout) const { fprintf(fout, "\n"); fprintf(fout, "per warp functional simulation status:\n"); @@ -2178,3 +2293,110 @@ const shader_core_config *gpgpu_sim::getShaderCoreConfig() { const memory_config *gpgpu_sim::getMemoryConfig() { return m_memory_config; } simt_core_cluster *gpgpu_sim::getSIMTCluster() { return *m_cluster; } + +void sst_gpgpu_sim::SST_gpgpusim_numcores_equal_check(unsigned sst_numcores) { + if (m_shader_config->n_simt_clusters != sst_numcores) { + assert( + "\nSST core is not equal the GPGPU-sim cores. Open gpgpu-sim.config " + "file and ensure n_simt_clusters" + "is the same as SST gpu cores.\n" && + 0); + } else { + printf("\nSST GPU core is equal the GPGPU-sim cores = %d\n", sst_numcores); + } +} + +void sst_gpgpu_sim::SST_cycle() { + // shader core loading (pop from ICNT into core) follows CORE clock + for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++) + static_cast<sst_simt_core_cluster *>(m_cluster[i])->icnt_cycle_SST(); + + // L1 cache + shader core pipeline stages + m_power_stats->pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].clear(); + for (unsigned i = 0; i < m_shader_config->n_simt_clusters; i++) { + if (m_cluster[i]->get_not_completed() || get_more_cta_left()) { + m_cluster[i]->core_cycle(); + *active_sms += m_cluster[i]->get_n_active_sms(); + } + // Update core icnt/cache stats for GPUWattch + m_cluster[i]->get_icnt_stats( + m_power_stats->pwr_mem_stat->n_simt_to_mem[CURRENT_STAT_IDX][i], + m_power_stats->pwr_mem_stat->n_mem_to_simt[CURRENT_STAT_IDX][i]); + m_cluster[i]->get_cache_stats( + m_power_stats->pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX]); + } + float temp = 0; + for (unsigned i = 0; i < m_shader_config->num_shader(); i++) { + temp += m_shader_stats->m_pipeline_duty_cycle[i]; + } + temp = temp / m_shader_config->num_shader(); + *average_pipeline_duty_cycle = ((*average_pipeline_duty_cycle) + temp); + // cout<<"Average pipeline duty cycle: "<<*average_pipeline_duty_cycle<<endl; + + if (g_single_step && ((gpu_sim_cycle + gpu_tot_sim_cycle) >= g_single_step)) { + asm("int $03"); + } + gpu_sim_cycle++; + if (g_interactive_debugger_enabled) gpgpu_debug(); + + // McPAT main cycle (interface with McPAT) +#ifdef GPGPUSIM_POWER_MODEL + if (m_config.g_power_simulation_enabled) { + mcpat_cycle(m_config, getShaderCoreConfig(), m_gpgpusim_wrapper, + m_power_stats, m_config.gpu_stat_sample_freq, gpu_tot_sim_cycle, + gpu_sim_cycle, gpu_tot_sim_insn, gpu_sim_insn, + m_config.g_dvfs_enabled); + } +#endif + + issue_block2core(); + + if (!(gpu_sim_cycle % m_config.gpu_stat_sample_freq)) { + time_t days, hrs, minutes, sec; + time_t curr_time; + time(&curr_time); + unsigned long long elapsed_time = + MAX(curr_time - gpgpu_ctx->the_gpgpusim->g_simulation_starttime, 1); + if ((elapsed_time - last_liveness_message_time) >= + m_config.liveness_message_freq) { + days = elapsed_time / (3600 * 24); + hrs = elapsed_time / 3600 - 24 * days; + minutes = elapsed_time / 60 - 60 * (hrs + 24 * days); + sec = elapsed_time - 60 * (minutes + 60 * (hrs + 24 * days)); + + last_liveness_message_time = elapsed_time; + } + visualizer_printstat(); + m_memory_stats->memlatstat_lat_pw(); + if (m_config.gpgpu_runtime_stat && (m_config.gpu_runtime_stat_flag != 0)) { + if (m_config.gpu_runtime_stat_flag & GPU_RSTAT_BW_STAT) { + for (unsigned i = 0; i < m_memory_config->m_n_mem; i++) + m_memory_partition_unit[i]->print_stat(stdout); + printf("maxmrqlatency = %d \n", m_memory_stats->max_mrq_latency); + printf("maxmflatency = %d \n", m_memory_stats->max_mf_latency); + } + if (m_config.gpu_runtime_stat_flag & GPU_RSTAT_SHD_INFO) + shader_print_runtime_stat(stdout); + if (m_config.gpu_runtime_stat_flag & GPU_RSTAT_L1MISS) + shader_print_l1_miss_stat(stdout); + if (m_config.gpu_runtime_stat_flag & GPU_RSTAT_SCHED) + shader_print_scheduler_stat(stdout, false); + } + } + + if (!(gpu_sim_cycle % 20000)) { + // deadlock detection + if (m_config.gpu_deadlock_detect && gpu_sim_insn == last_gpu_sim_insn) { + gpu_deadlock = true; + } else { + last_gpu_sim_insn = gpu_sim_insn; + } + } + try_snap_shot(gpu_sim_cycle); + spill_log_to_file(stdout, 0, gpu_sim_cycle); + +#if (CUDART_VERSION >= 5000) + // launch device kernel + gpgpu_ctx->device_runtime->launch_one_device_kernel(); +#endif +} diff --git a/src/gpgpu-sim/gpu-sim.h b/src/gpgpu-sim/gpu-sim.h index 68b3dfa..5b253ab 100644 --- a/src/gpgpu-sim/gpu-sim.h +++ b/src/gpgpu-sim/gpu-sim.h @@ -1,16 +1,18 @@ -// Copyright (c) 2009-2021, Tor M. Aamodt, Wilson W.L. Fung, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University +// Copyright (c) 2009-2021, Tor M. Aamodt, Wilson W.L. Fung, Vijay Kandiah, +// Nikos Hardavellas Mahmoud Khairy, Junrui Pan, Timothy G. Rogers The +// University of British Columbia, Northwestern University, Purdue University // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -27,7 +29,6 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. - #ifndef GPU_SIM_H #define GPU_SIM_H @@ -68,10 +69,50 @@ class gpgpu_context; extern tr1_hash_map<new_addr_type, unsigned> address_random_interleaving; +// SST communication functions +/** + * @brief Check if SST requests buffer is full + * + * @param core_id + * @return true + * @return false + */ +extern bool is_SST_buffer_full(unsigned core_id); +__attribute__((weak)) bool is_SST_buffer_full(unsigned core_id) { + return false; +} + +/** + * @brief Send loads to SST memory backend + * + * @param core_id + * @param address + * @param size + * @param mem_req + */ +extern void send_read_request_SST(unsigned core_id, uint64_t address, + size_t size, void *mem_req); +__attribute__((weak)) void send_read_request_SST(unsigned core_id, + uint64_t address, size_t size, + void *mem_req) {} +/** + * @brief Send stores to SST memory backend + * + * @param core_id + * @param address + * @param size + * @param mem_req + */ +extern void send_write_request_SST(unsigned core_id, uint64_t address, + size_t size, void *mem_req); +__attribute__((weak)) void send_write_request_SST(unsigned core_id, + uint64_t address, size_t size, + void *mem_req) {} + enum dram_ctrl_t { DRAM_FIFO = 0, DRAM_FRFCFS = 1 }; enum hw_perf_t { - HW_BENCH_NAME=0, + HW_BENCH_NAME = 0, HW_KERNEL_NAME, HW_L1_RH, HW_L1_RM, @@ -107,7 +148,7 @@ struct power_config { s++; } char buf1[1024]; - //snprintf(buf1, 1024, "accelwattch_power_report__%s.log", date); + // snprintf(buf1, 1024, "accelwattch_power_report__%s.log", date); snprintf(buf1, 1024, "accelwattch_power_report.log"); g_power_filename = strdup(buf1); char buf2[1024]; @@ -131,9 +172,9 @@ struct power_config { // NOTE: After changing the nonlinear model to only scaling idle core, // NOTE: The min_inc_per_active_sm is not used any more - if (g_use_nonlinear_model) - sscanf(gpu_nonlinear_model_config, "%lf:%lf", &gpu_idle_core_power, - &gpu_min_inc_per_active_sm); + // if (g_use_nonlinear_model) + // sscanf(gpu_nonlinear_model_config, "%lf:%lf", &gpu_idle_core_power, + // &gpu_min_inc_per_active_sm); } void reg_options(class OptionParser *opp); @@ -154,7 +195,6 @@ struct power_config { double gpu_steady_power_deviation; double gpu_steady_min_period; - char *g_hw_perf_file_name; char *g_hw_perf_bench_name; int g_power_simulation_mode; @@ -274,6 +314,14 @@ class memory_config { } void reg_options(class OptionParser *opp); + /** + * @brief Check if the config script is in SST mode + * + * @return true + * @return false + */ + bool is_SST_mode() const { return SST_mode; } + bool m_valid; mutable l2_cache_config m_L2_config; bool m_L2_texure_only; @@ -351,7 +399,7 @@ class memory_config { unsigned write_low_watermark; bool m_perf_sim_memcpy; bool simple_dram_model; - + bool SST_mode; gpgpu_context *gpgpu_ctx; }; @@ -398,6 +446,15 @@ class gpgpu_sim_config : public power_config, unsigned num_shader() const { return m_shader_config.num_shader(); } unsigned num_cluster() const { return m_shader_config.n_simt_clusters; } unsigned get_max_concurrent_kernel() const { return max_concurrent_kernel; } + + /** + * @brief Check if we are in SST mode + * + * @return true + * @return false + */ + bool is_SST_mode() const { return m_memory_config.SST_mode; } + unsigned checkpoint_option; size_t stack_limit() const { return stack_size_limit; } @@ -462,6 +519,7 @@ class gpgpu_sim_config : public power_config, unsigned long long liveness_message_freq; friend class gpgpu_sim; + friend class sst_gpgpu_sim; }; struct occupancy_stats { @@ -539,7 +597,7 @@ class gpgpu_sim : public gpgpu_t { (m_config.gpu_max_completed_cta_opt && (gpu_completed_cta >= m_config.gpu_max_completed_cta_opt)); } - void print_stats(); + void print_stats(unsigned long long streamID); void update_stats(); void deadlock_check(); void inc_completed_cta() { gpu_completed_cta++; } @@ -568,7 +626,7 @@ class gpgpu_sim : public gpgpu_t { void decrement_kernel_latency(); const gpgpu_sim_config &get_config() const { return m_config; } - void gpu_print_stat(); + void gpu_print_stat(unsigned long long streamID); void dump_pipeline(int mask, int s, int m) const; void perf_memcpy_to_gpu(size_t dst_start_addr, size_t count); @@ -600,10 +658,18 @@ class gpgpu_sim : public gpgpu_t { void hit_watchpoint(unsigned watchpoint_num, ptx_thread_info *thd, const ptx_instruction *pI); + /** + * @brief Check if we are in SST mode + * + * @return true + * @return false + */ + bool is_SST_mode() { return m_config.is_SST_mode(); } + // backward pointer class gpgpu_context *gpgpu_ctx; - private: + protected: // clocks void reinit_clock_domains(void); int next_clock_domain(void); @@ -685,6 +751,17 @@ class gpgpu_sim : public gpgpu_t { occupancy_stats gpu_occupancy; occupancy_stats gpu_tot_occupancy; + typedef struct { + unsigned long long start_cycle; + unsigned long long end_cycle; + } kernel_time_t; + std::map<unsigned long long, std::map<unsigned, kernel_time_t>> + gpu_kernel_time; + unsigned long long last_streamID; + unsigned long long last_uid; + cache_stats aggregated_l1_stats; + cache_stats aggregated_l2_stats; + // performance counter for stalls due to congestion. unsigned int gpu_stall_dramfull; unsigned int gpu_stall_icnt2sh; @@ -704,7 +781,7 @@ class gpgpu_sim : public gpgpu_t { void set_cache_config(std::string kernel_name); // Jin: functional simulation for CDP - private: + protected: // set by stream operation every time a functoinal simulation is done bool m_functional_sim; kernel_info_t *m_functional_sim_kernel; @@ -712,6 +789,9 @@ class gpgpu_sim : public gpgpu_t { public: bool is_functional_sim() { return m_functional_sim; } kernel_info_t *get_functional_kernel() { return m_functional_sim_kernel; } + std::vector<kernel_info_t *> get_running_kernels() { + return m_running_kernels; + } void functional_launch(kernel_info_t *k) { m_functional_sim = true; m_functional_sim_kernel = k; @@ -734,4 +814,79 @@ class exec_gpgpu_sim : public gpgpu_sim { virtual void createSIMTCluster(); }; +/** + * @brief A GPGPUSim class customized to SST Balar interfacing + * + */ +class sst_gpgpu_sim : public gpgpu_sim { + public: + sst_gpgpu_sim(const gpgpu_sim_config &config, gpgpu_context *ctx) + : gpgpu_sim(config, ctx) { + createSIMTCluster(); + } + + // SST memory handling + std::vector<std::deque<mem_fetch *>> + SST_gpgpu_reply_buffer; /** SST mem response queue */ + + /** + * @brief Receive mem request's response from SST and put + * it in a buffer (SST_gpgpu_reply_buffer) + * + * @param core_id + * @param mem_req + */ + void SST_receive_mem_reply(unsigned core_id, void *mem_req); + + /** + * @brief Pop the head of the buffer queue to get the + * memory response + * + * @param core_id + * @return mem_fetch* + */ + mem_fetch *SST_pop_mem_reply(unsigned core_id); + + virtual void createSIMTCluster(); + + // SST Balar interfacing + /** + * @brief Advance core and collect stats + * + */ + void SST_cycle(); + + /** + * @brief Wrapper of SST_cycle() + * + */ + void cycle(); + + /** + * @brief Whether the GPU is active, removed test for + * memory system since that is handled in SST + * + * @return true + * @return false + */ + bool active(); + + /** + * @brief SST mode use SST memory system instead, so the memcpy + * is empty here + * + * @param dst_start_addr + * @param count + */ + void perf_memcpy_to_gpu(size_t dst_start_addr, size_t count){}; + + /** + * @brief Check if the SST config matches up with the + * gpgpusim.config in core number + * + * @param sst_numcores SST core count + */ + void SST_gpgpusim_numcores_equal_check(unsigned sst_numcores); +}; + #endif diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc index 511c15e..52eed0e 100644 --- a/src/gpgpu-sim/l2cache.cc +++ b/src/gpgpu-sim/l2cache.cc @@ -1,16 +1,18 @@ -// Copyright (c) 2009-2021, Tor M. Aamodt, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// Copyright (c) 2009-2021, Tor M. Aamodt, Vijay Kandiah, Nikos Hardavellas, +// Mahmoud Khairy, Junrui Pan, Timothy G. Rogers +// The University of British Columbia, Northwestern University, Purdue +// University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -49,12 +51,12 @@ mem_fetch *partition_mf_allocator::alloc(new_addr_type addr, mem_access_type type, unsigned size, - bool wr, - unsigned long long cycle) const { + bool wr, unsigned long long cycle, + unsigned long long streamID) const { assert(wr); mem_access_t access(type, addr, size, wr, m_memory_config->gpgpu_ctx); - mem_fetch *mf = new mem_fetch(access, NULL, WRITE_PACKET_SIZE, -1, -1, -1, - m_memory_config, cycle); + mem_fetch *mf = new mem_fetch(access, NULL, streamID, WRITE_PACKET_SIZE, -1, + -1, -1, m_memory_config, cycle); return mf; } @@ -63,12 +65,12 @@ mem_fetch *partition_mf_allocator::alloc( const mem_access_byte_mask_t &byte_mask, const mem_access_sector_mask_t §or_mask, unsigned size, bool wr, unsigned long long cycle, unsigned wid, unsigned sid, unsigned tpc, - mem_fetch *original_mf) const { + mem_fetch *original_mf, unsigned long long streamID) const { mem_access_t access(type, addr, size, wr, active_mask, byte_mask, sector_mask, m_memory_config->gpgpu_ctx); - mem_fetch *mf = - new mem_fetch(access, NULL, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, - wid, sid, tpc, m_memory_config, cycle, original_mf); + mem_fetch *mf = new mem_fetch(access, NULL, streamID, + wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, wid, + sid, tpc, m_memory_config, cycle, original_mf); return mf; } memory_partition_unit::memory_partition_unit(unsigned partition_id, @@ -389,7 +391,8 @@ void memory_partition_unit::set_done(mem_fetch *mf) { void memory_partition_unit::set_dram_power_stats( unsigned &n_cmd, unsigned &n_activity, unsigned &n_nop, unsigned &n_act, - unsigned &n_pre, unsigned &n_rd, unsigned &n_wr, unsigned &n_wr_WB, unsigned &n_req) const { + unsigned &n_pre, unsigned &n_rd, unsigned &n_wr, unsigned &n_wr_WB, + unsigned &n_req) const { m_dram->set_dram_power_stats(n_cmd, n_activity, n_nop, n_act, n_pre, n_rd, n_wr, n_wr_WB, n_req); } @@ -433,9 +436,9 @@ memory_sub_partition::memory_sub_partition(unsigned sub_partition_id, m_mf_allocator = new partition_mf_allocator(config); if (!m_config->m_L2_config.disabled()) - m_L2cache = - new l2_cache(L2c_name, m_config->m_L2_config, -1, -1, m_L2interface, - m_mf_allocator, IN_PARTITION_L2_MISS_QUEUE, gpu); + m_L2cache = new l2_cache(L2c_name, m_config->m_L2_config, -1, -1, + m_L2interface, m_mf_allocator, + IN_PARTITION_L2_MISS_QUEUE, gpu, L2_GPU_CACHE); unsigned int icnt_L2; unsigned int L2_dram; @@ -558,7 +561,7 @@ void memory_sub_partition::cache_cycle(unsigned cycle) { if (mf->get_access_type() == L1_WRBK_ACC) { m_request_tracker.erase(mf); delete mf; - } else { + } else if (m_config->m_L2_config.get_write_policy() == WRITE_BACK) { mf->set_reply(); mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE, m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle); @@ -730,7 +733,7 @@ memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch *mf) { mf->get_access_warp_mask(), mf->get_access_byte_mask() & mask, std::bitset<SECTOR_CHUNCK_SIZE>().set(i), SECTOR_SIZE, mf->is_write(), m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, mf->get_wid(), - mf->get_sid(), mf->get_tpc(), mf); + mf->get_sid(), mf->get_tpc(), mf, mf->get_streamID()); result.push_back(n_mf); } @@ -753,7 +756,7 @@ memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch *mf) { mf->get_access_byte_mask() & mask, std::bitset<SECTOR_CHUNCK_SIZE>().set(i), SECTOR_SIZE, mf->is_write(), m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, mf->get_wid(), - mf->get_sid(), mf->get_tpc(), mf); + mf->get_sid(), mf->get_tpc(), mf, mf->get_streamID()); result.push_back(n_mf); } @@ -769,7 +772,8 @@ memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch *mf) { mf->get_access_warp_mask(), mf->get_access_byte_mask() & mask, std::bitset<SECTOR_CHUNCK_SIZE>().set(i), SECTOR_SIZE, mf->is_write(), m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, - mf->get_wid(), mf->get_sid(), mf->get_tpc(), mf); + mf->get_wid(), mf->get_sid(), mf->get_tpc(), mf, + mf->get_streamID()); result.push_back(n_mf); } diff --git a/src/gpgpu-sim/l2cache.h b/src/gpgpu-sim/l2cache.h index 902a4b7..65c9c38 100644 --- a/src/gpgpu-sim/l2cache.h +++ b/src/gpgpu-sim/l2cache.h @@ -1,16 +1,18 @@ -// Copyright (c) 2009-2021, Tor M. Aamodt, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// Copyright (c) 2009-2021, Tor M. Aamodt, Vijay Kandiah, Nikos Hardavellas, +// Mahmoud Khairy, Junrui Pan, Timothy G. Rogers +// The University of British Columbia, Northwestern University, Purdue +// University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -50,15 +52,16 @@ class partition_mf_allocator : public mem_fetch_allocator { return NULL; } virtual mem_fetch *alloc(new_addr_type addr, mem_access_type type, - unsigned size, bool wr, - unsigned long long cycle) const; + unsigned size, bool wr, unsigned long long cycle, + unsigned long long streamID) const; virtual mem_fetch *alloc(new_addr_type addr, mem_access_type type, const active_mask_t &active_mask, const mem_access_byte_mask_t &byte_mask, const mem_access_sector_mask_t §or_mask, unsigned size, bool wr, unsigned long long cycle, unsigned wid, unsigned sid, unsigned tpc, - mem_fetch *original_mf) const; + mem_fetch *original_mf, + unsigned long long streamID) const; private: const memory_config *m_memory_config; diff --git a/src/gpgpu-sim/local_interconnect.cc b/src/gpgpu-sim/local_interconnect.cc index 0e20462..7e1ab5b 100644 --- a/src/gpgpu-sim/local_interconnect.cc +++ b/src/gpgpu-sim/local_interconnect.cc @@ -148,8 +148,8 @@ void xbar_router::RR_Advance() { } } } - - next_node_id = (++next_node_id % total_nodes); + next_node_id = next_node_id + 1; + next_node_id = (next_node_id % total_nodes); conflicts += conflict_sub; if (active) { @@ -159,8 +159,8 @@ void xbar_router::RR_Advance() { } if (verbose) { - printf("%d : cycle %d : conflicts = %d\n", m_id, cycles, conflict_sub); - printf("%d : cycle %d : passing reqs = %d\n", m_id, cycles, reqs); + printf("%d : cycle %llu : conflicts = %d\n", m_id, cycles, conflict_sub); + printf("%d : cycle %llu : passing reqs = %d\n", m_id, cycles, reqs); } // collect some stats about buffer util @@ -217,7 +217,7 @@ void xbar_router::iSLIP_Advance() { out_buffers[_packet.output_deviceID].push(_packet); in_buffers[node_id].pop(); if (verbose) - printf("%d : cycle %d : send req from %d to %d\n", m_id, cycles, + printf("%d : cycle %llu : send req from %d to %d\n", m_id, cycles, node_id, i - _n_shader); if (grant_cycles_count == 1) next_node[i] = (++node_id % total_nodes); @@ -228,7 +228,7 @@ void xbar_router::iSLIP_Advance() { Packet _packet2 = in_buffers[node_id2].front(); if (_packet2.output_deviceID == i) - printf("%d : cycle %d : cannot send req from %d to %d\n", + printf("%d : cycle %llu : cannot send req from %d to %d\n", m_id, cycles, node_id2, i - _n_shader); } } @@ -248,7 +248,7 @@ void xbar_router::iSLIP_Advance() { } if (verbose) - printf("%d : cycle %d : grant_cycles = %d\n", m_id, cycles, grant_cycles); + printf("%d : cycle %llu : grant_cycles = %d\n", m_id, cycles, grant_cycles); if (active && grant_cycles_count == 1) grant_cycles_count = grant_cycles; @@ -256,8 +256,8 @@ void xbar_router::iSLIP_Advance() { grant_cycles_count--; if (verbose) { - printf("%d : cycle %d : conflicts = %d\n", m_id, cycles, conflict_sub); - printf("%d : cycle %d : passing reqs = %d\n", m_id, cycles, reqs); + printf("%d : cycle %llu : conflicts = %d\n", m_id, cycles, conflict_sub); + printf("%d : cycle %llu : passing reqs = %d\n", m_id, cycles, reqs); } // collect some stats about buffer util diff --git a/src/gpgpu-sim/mem_fetch.cc b/src/gpgpu-sim/mem_fetch.cc index 456d891..809c920 100644 --- a/src/gpgpu-sim/mem_fetch.cc +++ b/src/gpgpu-sim/mem_fetch.cc @@ -35,10 +35,10 @@ unsigned mem_fetch::sm_next_mf_request_uid = 1; mem_fetch::mem_fetch(const mem_access_t &access, const warp_inst_t *inst, - unsigned ctrl_size, unsigned wid, unsigned sid, - unsigned tpc, const memory_config *config, - unsigned long long cycle, mem_fetch *m_original_mf, - mem_fetch *m_original_wr_mf) + unsigned long long streamID, unsigned ctrl_size, + unsigned wid, unsigned sid, unsigned tpc, + const memory_config *config, unsigned long long cycle, + mem_fetch *m_original_mf, mem_fetch *m_original_wr_mf) : m_access(access) { @@ -48,14 +48,21 @@ mem_fetch::mem_fetch(const mem_access_t &access, const warp_inst_t *inst, m_inst = *inst; assert(wid == m_inst.warp_id()); } + m_streamID = streamID; m_data_size = access.get_size(); m_ctrl_size = ctrl_size; m_sid = sid; m_tpc = tpc; m_wid = wid; - config->m_address_mapping.addrdec_tlx(access.get_addr(), &m_raw_addr); - m_partition_addr = - config->m_address_mapping.partition_address(access.get_addr()); + + if (!config->is_SST_mode()) { + // In SST memory model, the SST memory hierarchy is + // responsible to generate the correct address mapping + config->m_address_mapping.addrdec_tlx(access.get_addr(), &m_raw_addr); + m_partition_addr = + config->m_address_mapping.partition_address(access.get_addr()); + } + m_type = m_access.is_write() ? WRITE_REQUEST : READ_REQUEST; m_timestamp = cycle; m_timestamp2 = 0; @@ -84,10 +91,10 @@ mem_fetch::~mem_fetch() { m_status = MEM_FETCH_DELETED; } #undef MF_TUP_END void mem_fetch::print(FILE *fp, bool print_inst) const { - if (this == NULL) { - fprintf(fp, " <NULL mem_fetch pointer>\n"); - return; - } + // if (this == NULL) { // doenst make sense! + // fprintf(fp, " <NULL mem_fetch pointer>\n"); + // return; + // } fprintf(fp, " mf: uid=%6u, sid%02u:w%02u, part=%u, ", m_request_uid, m_sid, m_wid, m_raw_addr.chip); m_access.print(fp); diff --git a/src/gpgpu-sim/mem_fetch.h b/src/gpgpu-sim/mem_fetch.h index e039846..7704218 100644 --- a/src/gpgpu-sim/mem_fetch.h +++ b/src/gpgpu-sim/mem_fetch.h @@ -54,9 +54,10 @@ class memory_config; class mem_fetch { public: mem_fetch(const mem_access_t &access, const warp_inst_t *inst, - unsigned ctrl_size, unsigned wid, unsigned sid, unsigned tpc, - const memory_config *config, unsigned long long cycle, - mem_fetch *original_mf = NULL, mem_fetch *original_wr_mf = NULL); + unsigned long long streamID, unsigned ctrl_size, unsigned wid, + unsigned sid, unsigned tpc, const memory_config *config, + unsigned long long cycle, mem_fetch *original_mf = NULL, + mem_fetch *original_wr_mf = NULL); ~mem_fetch(); void set_status(enum mem_fetch_status status, unsigned long long cycle); @@ -77,7 +78,7 @@ class mem_fetch { const addrdec_t &get_tlx_addr() const { return m_raw_addr; } void set_chip(unsigned chip_id) { m_raw_addr.chip = chip_id; } - void set_parition(unsigned sub_partition_id) { + void set_partition(unsigned sub_partition_id) { m_raw_addr.sub_partition = sub_partition_id; } unsigned get_data_size() const { return m_data_size; } @@ -105,6 +106,7 @@ class mem_fetch { unsigned get_timestamp() const { return m_timestamp; } unsigned get_return_timestamp() const { return m_timestamp2; } unsigned get_icnt_receive_time() const { return m_icnt_receive_time; } + unsigned long long get_streamID() const { return m_streamID; } enum mem_access_type get_access_type() const { return m_access.get_type(); } const active_mask_t &get_access_warp_mask() const { @@ -163,6 +165,8 @@ class mem_fetch { // requesting instruction (put last so mem_fetch prints nicer in gdb) warp_inst_t m_inst; + unsigned long long m_streamID; + static unsigned sm_next_mf_request_uid; const memory_config *m_mem_config; diff --git a/src/gpgpu-sim/mem_latency_stat.cc b/src/gpgpu-sim/mem_latency_stat.cc index 63d7ee8..c77a686 100644 --- a/src/gpgpu-sim/mem_latency_stat.cc +++ b/src/gpgpu-sim/mem_latency_stat.cc @@ -203,7 +203,15 @@ unsigned memory_stats_t::memlatstat_done(mem_fetch *mf) { } void memory_stats_t::memlatstat_read_done(mem_fetch *mf) { - if (m_memory_config->gpgpu_memlatency_stat) { + if (m_memory_config->SST_mode) { + // in SST mode, we just calculate mem latency + unsigned mf_latency; + mf_latency = + (m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle) - mf->get_timestamp(); + num_mfs++; + mf_total_lat += mf_latency; + if (mf_latency > max_mf_latency) max_mf_latency = mf_latency; + } else if (m_memory_config->gpgpu_memlatency_stat) { unsigned mf_latency = memlatstat_done(mf); if (mf_latency > mf_max_lat_table[mf->get_tlx_addr().chip][mf->get_tlx_addr().bk]) @@ -273,7 +281,12 @@ void memory_stats_t::memlatstat_print(unsigned n_mem, unsigned gpu_mem_n_bk) { unsigned max_bank_accesses, min_bank_accesses, max_chip_accesses, min_chip_accesses; - if (m_memory_config->gpgpu_memlatency_stat) { + if (m_memory_config->SST_mode) { + // in SST mode, we just calculate mem latency + printf("max_mem_SST_latency = %d \n", max_mf_latency); + if (num_mfs) + printf("average_mf_SST_latency = %lld \n", mf_total_lat / num_mfs); + } else if (m_memory_config->gpgpu_memlatency_stat) { printf("maxmflatency = %d \n", max_mf_latency); printf("max_icnt2mem_latency = %d \n", max_icnt2mem_latency); printf("maxmrqlatency = %d \n", max_mrq_latency); diff --git a/src/gpgpu-sim/power_interface.cc b/src/gpgpu-sim/power_interface.cc index 63b9852..cddb6e9 100644 --- a/src/gpgpu-sim/power_interface.cc +++ b/src/gpgpu-sim/power_interface.cc @@ -1,16 +1,18 @@ -// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, Tayler Hetherington, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, Tayler +// Hetherington, Vijay Kandiah, Nikos Hardavellas, Mahmoud Khairy, Junrui Pan, +// Timothy G. Rogers The University of British Columbia, Northwestern +// University, Purdue University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -27,10 +29,8 @@ // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE // POSSIBILITY OF SUCH DAMAGE. - #include "power_interface.h" - void init_mcpat(const gpgpu_sim_config &config, class gpgpu_sim_wrapper *wrapper, unsigned stat_sample_freq, unsigned tot_inst, unsigned inst) { @@ -41,11 +41,9 @@ void init_mcpat(const gpgpu_sim_config &config, config.g_power_simulation_enabled, config.g_power_trace_enabled, config.g_steady_power_levels_enabled, config.g_power_per_cycle_dump, config.gpu_steady_power_deviation, config.gpu_steady_min_period, - config.g_power_trace_zlevel, tot_inst + inst, stat_sample_freq, - config.g_power_simulation_mode, - config.g_dvfs_enabled, - config.get_core_freq()/1000000, - config.num_shader()); + config.g_power_trace_zlevel, tot_inst + inst, stat_sample_freq, + config.g_power_simulation_mode, config.g_dvfs_enabled, + config.get_core_freq() / 1000000, config.num_shader()); } void mcpat_cycle(const gpgpu_sim_config &config, @@ -62,8 +60,9 @@ void mcpat_cycle(const gpgpu_sim_config &config, } if ((tot_cycle + cycle) % stat_sample_freq == 0) { - if(dvfs_enabled){ - wrapper->set_model_voltage(1); //performance model needs to support this. + if (dvfs_enabled) { + wrapper->set_model_voltage(1); // performance model needs to support + // this. } wrapper->set_inst_power( @@ -84,14 +83,17 @@ void mcpat_cycle(const gpgpu_sim_config &config, power_stats->get_inst_c_misses(0)); // Constant Cache, shared memory, texture cache - wrapper->set_ccache_power(power_stats->get_const_accessess(0), 0); //assuming all HITS in constant cache for now + wrapper->set_ccache_power( + power_stats->get_const_accessess(0), + 0); // assuming all HITS in constant cache for now wrapper->set_tcache_power(power_stats->get_texture_c_hits(), power_stats->get_texture_c_misses()); wrapper->set_shrd_mem_power(power_stats->get_shmem_access(0)); - wrapper->set_l1cache_power( - power_stats->get_l1d_read_hits(0), power_stats->get_l1d_read_misses(0), - power_stats->get_l1d_write_hits(0), power_stats->get_l1d_write_misses(0)); + wrapper->set_l1cache_power(power_stats->get_l1d_read_hits(0), + power_stats->get_l1d_read_misses(0), + power_stats->get_l1d_write_hits(0), + power_stats->get_l1d_write_misses(0)); wrapper->set_l2cache_power( power_stats->get_l2_read_hits(0), power_stats->get_l2_read_misses(0), @@ -119,24 +121,23 @@ void mcpat_cycle(const gpgpu_sim_config &config, // Execution pipeline accesses // FPU (SP) accesses, Integer ALU (not present in Tesla), Sfu accesses - wrapper->set_int_accesses(power_stats->get_ialu_accessess(0), - power_stats->get_intmul24_accessess(0), - power_stats->get_intmul32_accessess(0), - power_stats->get_intmul_accessess(0), + wrapper->set_int_accesses(power_stats->get_ialu_accessess(0), + power_stats->get_intmul24_accessess(0), + power_stats->get_intmul32_accessess(0), + power_stats->get_intmul_accessess(0), power_stats->get_intdiv_accessess(0)); - wrapper->set_dp_accesses(power_stats->get_dp_accessess(0), - power_stats->get_dpmul_accessess(0), - power_stats->get_dpdiv_accessess(0)); + wrapper->set_dp_accesses(power_stats->get_dp_accessess(0), + power_stats->get_dpmul_accessess(0), + power_stats->get_dpdiv_accessess(0)); - wrapper->set_fp_accesses(power_stats->get_fp_accessess(0), - power_stats->get_fpmul_accessess(0), - power_stats->get_fpdiv_accessess(0)); + wrapper->set_fp_accesses(power_stats->get_fp_accessess(0), + power_stats->get_fpmul_accessess(0), + power_stats->get_fpdiv_accessess(0)); - wrapper->set_trans_accesses(power_stats->get_sqrt_accessess(0), - power_stats->get_log_accessess(0), - power_stats->get_sin_accessess(0), - power_stats->get_exp_accessess(0)); + wrapper->set_trans_accesses( + power_stats->get_sqrt_accessess(0), power_stats->get_log_accessess(0), + power_stats->get_sin_accessess(0), power_stats->get_exp_accessess(0)); wrapper->set_tensor_accesses(power_stats->get_tensor_accessess(0)); @@ -153,23 +154,21 @@ void mcpat_cycle(const gpgpu_sim_config &config, (power_stats->get_sp_active_lanes()) / stat_sample_freq; float avg_sfu_active_lanes = (power_stats->get_sfu_active_lanes()) / stat_sample_freq; - if(avg_sp_active_lanes >32.0 ) - avg_sp_active_lanes = 32.0; - if(avg_sfu_active_lanes >32.0 ) - avg_sfu_active_lanes = 32.0; + if (avg_sp_active_lanes > 32.0) avg_sp_active_lanes = 32.0; + if (avg_sfu_active_lanes > 32.0) avg_sfu_active_lanes = 32.0; assert(avg_sp_active_lanes <= 32); assert(avg_sfu_active_lanes <= 32); wrapper->set_active_lanes_power(avg_sp_active_lanes, avg_sfu_active_lanes); - double n_icnt_simt_to_mem = - (double) - power_stats->get_icnt_simt_to_mem(0); // # flits from SIMT clusters - // to memory partitions - double n_icnt_mem_to_simt = - (double) - power_stats->get_icnt_mem_to_simt(0); // # flits from memory - // partitions to SIMT clusters - wrapper->set_NoC_power(n_icnt_mem_to_simt + n_icnt_simt_to_mem); // Number of flits traversing the interconnect + double n_icnt_simt_to_mem = (double)power_stats->get_icnt_simt_to_mem( + 0); // # flits from SIMT clusters + // to memory partitions + double n_icnt_mem_to_simt = (double)power_stats->get_icnt_mem_to_simt( + 0); // # flits from memory + // partitions to SIMT clusters + wrapper->set_NoC_power( + n_icnt_mem_to_simt + + n_icnt_simt_to_mem); // Number of flits traversing the interconnect wrapper->compute(); @@ -190,68 +189,77 @@ void mcpat_reset_perf_count(class gpgpu_sim_wrapper *wrapper) { wrapper->reset_counters(); } -bool parse_hw_file(char* hwpowerfile, bool find_target_kernel, vector<string> &hw_data, char* benchname, std::string executed_kernelname){ +bool parse_hw_file(char *hwpowerfile, bool find_target_kernel, + vector<string> &hw_data, char *benchname, + std::string executed_kernelname) { fstream hw_file; hw_file.open(hwpowerfile, ios::in); string line, word, temp; - while(!hw_file.eof()){ + while (!hw_file.eof()) { hw_data.clear(); getline(hw_file, line); stringstream s(line); - while (getline(s,word,',')){ + while (getline(s, word, ',')) { hw_data.push_back(word); } - if(hw_data[HW_BENCH_NAME] == std::string(benchname)){ - if(find_target_kernel){ - if(hw_data[HW_KERNEL_NAME] == ""){ + if (hw_data[HW_BENCH_NAME] == std::string(benchname)) { + if (find_target_kernel) { + if (hw_data[HW_KERNEL_NAME] == "") { hw_file.close(); return true; - } - else{ - if(hw_data[HW_KERNEL_NAME] == executed_kernelname){ + } else { + if (hw_data[HW_KERNEL_NAME] == executed_kernelname) { hw_file.close(); return true; } } - } - else{ + } else { hw_file.close(); return true; } - } + } } hw_file.close(); return false; } - -void calculate_hw_mcpat(const gpgpu_sim_config &config, - const shader_core_config *shdr_config, - class gpgpu_sim_wrapper *wrapper, - class power_stat_t *power_stats, unsigned stat_sample_freq, - unsigned tot_cycle, unsigned cycle, unsigned tot_inst, - unsigned inst, int power_simulation_mode, bool dvfs_enabled, char* hwpowerfile, - char* benchname, std::string executed_kernelname, - const bool *accelwattch_hybrid_configuration, bool aggregate_power_stats){ - +void calculate_hw_mcpat( + const gpgpu_sim_config &config, const shader_core_config *shdr_config, + class gpgpu_sim_wrapper *wrapper, class power_stat_t *power_stats, + unsigned stat_sample_freq, unsigned tot_cycle, unsigned cycle, + unsigned tot_inst, unsigned inst, int power_simulation_mode, + bool dvfs_enabled, char *hwpowerfile, char *benchname, + std::string executed_kernelname, + const bool *accelwattch_hybrid_configuration, bool aggregate_power_stats) { /* Reading HW data from CSV file */ vector<string> hw_data; bool kernel_found = false; - kernel_found = parse_hw_file(hwpowerfile, true, hw_data, benchname, executed_kernelname); //Searching for matching executed_kernelname. - if(!kernel_found) - kernel_found = parse_hw_file(hwpowerfile, false, hw_data, benchname, executed_kernelname); //Searching for any kernel with same benchname. - assert("Could not find perf stats for the target benchmark in hwpowerfile.\n" && (kernel_found)); - unsigned perf_cycles = static_cast<unsigned int>(std::stod(hw_data[HW_CYCLES]) + 0.5); - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_CYCLES])) + kernel_found = parse_hw_file( + hwpowerfile, true, hw_data, benchname, + executed_kernelname); // Searching for matching executed_kernelname. + if (!kernel_found) + kernel_found = parse_hw_file( + hwpowerfile, false, hw_data, benchname, + executed_kernelname); // Searching for any kernel with same benchname. + assert( + "Could not find perf stats for the target benchmark in hwpowerfile.\n" && + (kernel_found)); + unsigned perf_cycles = + static_cast<unsigned int>(std::stod(hw_data[HW_CYCLES]) + 0.5); + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_CYCLES])) perf_cycles = cycle; - wrapper->init_mcpat_hw_mode(perf_cycles); //total PERF MODEL cycles for current kernel + wrapper->init_mcpat_hw_mode( + perf_cycles); // total PERF MODEL cycles for current kernel - if(dvfs_enabled){ - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_VOLTAGE])) - wrapper->set_model_voltage(1); //performance model needs to support this - else - wrapper->set_model_voltage(std::stod(hw_data[HW_VOLTAGE])); //performance model needs to support this + if (dvfs_enabled) { + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_VOLTAGE])) + wrapper->set_model_voltage(1); // performance model needs to support this + else + wrapper->set_model_voltage(std::stod( + hw_data[HW_VOLTAGE])); // performance model needs to support this } double l1_read_hits = std::stod(hw_data[HW_L1_RH]); @@ -259,266 +267,302 @@ void calculate_hw_mcpat(const gpgpu_sim_config &config, double l1_write_hits = std::stod(hw_data[HW_L1_WH]); double l1_write_misses = std::stod(hw_data[HW_L1_WM]); - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L1_RH])) - l1_read_hits = power_stats->get_l1d_read_hits(1) - power_stats->l1r_hits_kernel; - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L1_RM])) - l1_read_misses = power_stats->get_l1d_read_misses(1) - power_stats->l1r_misses_kernel; - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L1_WH])) - l1_write_hits = power_stats->get_l1d_write_hits(1) - power_stats->l1w_hits_kernel; - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L1_WM])) - l1_write_misses = power_stats->get_l1d_write_misses(1) - power_stats->l1w_misses_kernel; + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_L1_RH])) + l1_read_hits = + power_stats->get_l1d_read_hits(1) - power_stats->l1r_hits_kernel; + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_L1_RM])) + l1_read_misses = + power_stats->get_l1d_read_misses(1) - power_stats->l1r_misses_kernel; + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_L1_WH])) + l1_write_hits = + power_stats->get_l1d_write_hits(1) - power_stats->l1w_hits_kernel; + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_L1_WM])) + l1_write_misses = + power_stats->get_l1d_write_misses(1) - power_stats->l1w_misses_kernel; - if(aggregate_power_stats){ - power_stats->tot_inst_execution += power_stats->get_total_inst(1); - power_stats->tot_int_inst_execution += power_stats->get_total_int_inst(1); - power_stats->tot_fp_inst_execution += power_stats->get_total_fp_inst(1); - power_stats->commited_inst_execution += power_stats->get_committed_inst(1); - wrapper->set_inst_power( - shdr_config->gpgpu_clock_gated_lanes, cycle, //TODO: core.[0] cycles counts don't matter, remove this + if (aggregate_power_stats) { + power_stats->tot_inst_execution += power_stats->get_total_inst(1); + power_stats->tot_int_inst_execution += power_stats->get_total_int_inst(1); + power_stats->tot_fp_inst_execution += power_stats->get_total_fp_inst(1); + power_stats->commited_inst_execution += power_stats->get_committed_inst(1); + wrapper->set_inst_power( + shdr_config->gpgpu_clock_gated_lanes, + cycle, // TODO: core.[0] cycles counts don't matter, remove this cycle, power_stats->tot_inst_execution, power_stats->tot_int_inst_execution, power_stats->tot_fp_inst_execution, - l1_read_hits + l1_read_misses, - l1_write_hits + l1_write_misses, + l1_read_hits + l1_read_misses, l1_write_hits + l1_write_misses, power_stats->commited_inst_execution); - } - else{ + } else { wrapper->set_inst_power( - shdr_config->gpgpu_clock_gated_lanes, cycle, //TODO: core.[0] cycles counts don't matter, remove this + shdr_config->gpgpu_clock_gated_lanes, + cycle, // TODO: core.[0] cycles counts don't matter, remove this cycle, power_stats->get_total_inst(1), power_stats->get_total_int_inst(1), power_stats->get_total_fp_inst(1), - l1_read_hits + l1_read_misses, - l1_write_hits + l1_write_misses, + l1_read_hits + l1_read_misses, l1_write_hits + l1_write_misses, power_stats->get_committed_inst(1)); - } + } - // Single RF for both int and fp ops -- activity factor set to 0 for Accelwattch HW and Accelwattch Hybrid because no HW Perf Stats for register files - wrapper->set_regfile_power(power_stats->get_regfile_reads(1), - power_stats->get_regfile_writes(1), - power_stats->get_non_regfile_operands(1)); + // Single RF for both int and fp ops -- activity factor set to 0 for + // Accelwattch HW and Accelwattch Hybrid because no HW Perf Stats for register + // files + wrapper->set_regfile_power(power_stats->get_regfile_reads(1), + power_stats->get_regfile_writes(1), + power_stats->get_non_regfile_operands(1)); - // Instruction cache stats -- activity factor set to 0 for Accelwattch HW and Accelwattch Hybrid because no HW Perf Stats for instruction cache - wrapper->set_icache_power(power_stats->get_inst_c_hits(1) - power_stats->l1i_hits_kernel, - power_stats->get_inst_c_misses(1) - power_stats->l1i_misses_kernel); + // Instruction cache stats -- activity factor set to 0 for Accelwattch HW and + // Accelwattch Hybrid because no HW Perf Stats for instruction cache + wrapper->set_icache_power( + power_stats->get_inst_c_hits(1) - power_stats->l1i_hits_kernel, + power_stats->get_inst_c_misses(1) - power_stats->l1i_misses_kernel); - // Constant Cache, shared memory, texture cache - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_CC_ACC])) - wrapper->set_ccache_power(power_stats->get_const_accessess(1) - power_stats->cc_accesses_kernel, 0); //assuming all HITS in constant cache for now - else - wrapper->set_ccache_power(std::stod(hw_data[HW_CC_ACC]), 0); //assuming all HITS in constant cache for now + // Constant Cache, shared memory, texture cache + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_CC_ACC])) + wrapper->set_ccache_power( + power_stats->get_const_accessess(1) - power_stats->cc_accesses_kernel, + 0); // assuming all HITS in constant cache for now + else + wrapper->set_ccache_power( + std::stod(hw_data[HW_CC_ACC]), + 0); // assuming all HITS in constant cache for now - - // wrapper->set_tcache_power(power_stats->get_texture_c_hits(), - // power_stats->get_texture_c_misses()); + // wrapper->set_tcache_power(power_stats->get_texture_c_hits(), + // power_stats->get_texture_c_misses()); - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_SHRD_ACC])) - wrapper->set_shrd_mem_power(power_stats->get_shmem_access(1) - power_stats->shared_accesses_kernel); - else - wrapper->set_shrd_mem_power(std::stod(hw_data[HW_SHRD_ACC])); + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_SHRD_ACC])) + wrapper->set_shrd_mem_power(power_stats->get_shmem_access(1) - + power_stats->shared_accesses_kernel); + else + wrapper->set_shrd_mem_power(std::stod(hw_data[HW_SHRD_ACC])); - wrapper->set_l1cache_power( l1_read_hits, l1_read_misses, l1_write_hits, l1_write_misses); + wrapper->set_l1cache_power(l1_read_hits, l1_read_misses, l1_write_hits, + l1_write_misses); - double l2_read_hits = std::stod(hw_data[HW_L2_RH]); - double l2_read_misses = std::stod(hw_data[HW_L2_RM]); - double l2_write_hits = std::stod(hw_data[HW_L2_WH]); - double l2_write_misses = std::stod(hw_data[HW_L2_WM]); + double l2_read_hits = std::stod(hw_data[HW_L2_RH]); + double l2_read_misses = std::stod(hw_data[HW_L2_RM]); + double l2_write_hits = std::stod(hw_data[HW_L2_WH]); + double l2_write_misses = std::stod(hw_data[HW_L2_WM]); - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L2_RH])) - l2_read_hits = power_stats->get_l2_read_hits(1) - power_stats->l2r_hits_kernel; - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L2_RM])) - l2_read_misses = power_stats->get_l2_read_misses(1) - power_stats->l2r_misses_kernel; - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L2_WH])) - l2_write_hits = power_stats->get_l2_write_hits(1) - power_stats->l2w_hits_kernel; - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_L2_WM])) - l2_write_misses = power_stats->get_l2_write_misses(1) - power_stats->l2w_misses_kernel; + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_L2_RH])) + l2_read_hits = + power_stats->get_l2_read_hits(1) - power_stats->l2r_hits_kernel; + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_L2_RM])) + l2_read_misses = + power_stats->get_l2_read_misses(1) - power_stats->l2r_misses_kernel; + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_L2_WH])) + l2_write_hits = + power_stats->get_l2_write_hits(1) - power_stats->l2w_hits_kernel; + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_L2_WM])) + l2_write_misses = + power_stats->get_l2_write_misses(1) - power_stats->l2w_misses_kernel; - wrapper->set_l2cache_power(l2_read_hits, l2_read_misses, l2_write_hits, l2_write_misses); - - float active_sms = (*power_stats->m_active_sms) / stat_sample_freq; - float num_cores = shdr_config->num_shader(); - float num_idle_core = num_cores - active_sms; - wrapper->set_num_cores(num_cores); - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_NUM_SM_IDLE])) - wrapper->set_idle_core_power(num_idle_core); - else - wrapper->set_idle_core_power(std::stod(hw_data[HW_NUM_SM_IDLE])); + wrapper->set_l2cache_power(l2_read_hits, l2_read_misses, l2_write_hits, + l2_write_misses); - float pipeline_duty_cycle = - ((*power_stats->m_average_pipeline_duty_cycle / (stat_sample_freq)) < - 0.8) - ? ((*power_stats->m_average_pipeline_duty_cycle) / stat_sample_freq) - : 0.8; - - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_PIPE_DUTY])) - wrapper->set_duty_cycle_power(pipeline_duty_cycle); - else - wrapper->set_duty_cycle_power(std::stod(hw_data[HW_PIPE_DUTY])); + float active_sms = (*power_stats->m_active_sms) / stat_sample_freq; + float num_cores = shdr_config->num_shader(); + float num_idle_core = num_cores - active_sms; + wrapper->set_num_cores(num_cores); + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_NUM_SM_IDLE])) + wrapper->set_idle_core_power(num_idle_core); + else + wrapper->set_idle_core_power(std::stod(hw_data[HW_NUM_SM_IDLE])); - // Memory Controller - - double dram_reads = std::stod(hw_data[HW_DRAM_RD]); - double dram_writes = std::stod(hw_data[HW_DRAM_WR]); - double dram_pre = 0; - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_DRAM_RD])) - dram_reads = power_stats->get_dram_rd(1) - power_stats->dram_rd_kernel; - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_DRAM_WR])) - dram_writes = power_stats->get_dram_wr(1) - power_stats->dram_wr_kernel; - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_DRAM_RD])) - dram_pre = power_stats->get_dram_pre(1) - power_stats->dram_pre_kernel; + float pipeline_duty_cycle = + ((*power_stats->m_average_pipeline_duty_cycle / (stat_sample_freq)) < 0.8) + ? ((*power_stats->m_average_pipeline_duty_cycle) / stat_sample_freq) + : 0.8; + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_PIPE_DUTY])) + wrapper->set_duty_cycle_power(pipeline_duty_cycle); + else + wrapper->set_duty_cycle_power(std::stod(hw_data[HW_PIPE_DUTY])); - wrapper->set_mem_ctrl_power(dram_reads, dram_writes, dram_pre); + // Memory Controller - if(aggregate_power_stats){ - power_stats->ialu_acc_execution += power_stats->get_ialu_accessess(1); - power_stats->imul24_acc_execution += power_stats->get_intmul24_accessess(1); - power_stats->imul32_acc_execution += power_stats->get_intmul32_accessess(1); - power_stats->imul_acc_execution += power_stats->get_intmul_accessess(1); - power_stats->idiv_acc_execution += power_stats->get_intdiv_accessess(1); - power_stats->dp_acc_execution += power_stats->get_dp_accessess(1); - power_stats->dpmul_acc_execution += power_stats->get_dpmul_accessess(1); - power_stats->dpdiv_acc_execution += power_stats->get_dpdiv_accessess(1); - power_stats->fp_acc_execution += power_stats->get_fp_accessess(1); - power_stats->fpmul_acc_execution += power_stats->get_fpmul_accessess(1); - power_stats->fpdiv_acc_execution += power_stats->get_fpdiv_accessess(1); - power_stats->sqrt_acc_execution += power_stats->get_sqrt_accessess(1); - power_stats->log_acc_execution += power_stats->get_log_accessess(1); - power_stats->sin_acc_execution += power_stats->get_sin_accessess(1); - power_stats->exp_acc_execution += power_stats->get_exp_accessess(1); - power_stats->tensor_acc_execution += power_stats->get_tensor_accessess(1); - power_stats->tex_acc_execution += power_stats->get_tex_accessess(1); - power_stats->tot_fpu_acc_execution += power_stats->get_tot_fpu_accessess(1); - power_stats->tot_sfu_acc_execution += power_stats->get_tot_sfu_accessess(1); - power_stats->tot_threads_acc_execution += power_stats->get_tot_threads_kernel(1); - power_stats->tot_warps_acc_execution += power_stats->get_tot_warps_kernel(1); - - power_stats->sp_active_lanes_execution += (power_stats->get_sp_active_lanes() * shdr_config->num_shader() * shdr_config->gpgpu_num_sp_units); - power_stats->sfu_active_lanes_execution += (power_stats->get_sfu_active_lanes() * shdr_config->num_shader() * shdr_config->gpgpu_num_sp_units); + double dram_reads = std::stod(hw_data[HW_DRAM_RD]); + double dram_writes = std::stod(hw_data[HW_DRAM_WR]); + double dram_pre = 0; + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_DRAM_RD])) + dram_reads = power_stats->get_dram_rd(1) - power_stats->dram_rd_kernel; + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_DRAM_WR])) + dram_writes = power_stats->get_dram_wr(1) - power_stats->dram_wr_kernel; + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_DRAM_RD])) + dram_pre = power_stats->get_dram_pre(1) - power_stats->dram_pre_kernel; - wrapper->set_int_accesses(power_stats->ialu_acc_execution, - power_stats->imul24_acc_execution, - power_stats->imul32_acc_execution, - power_stats->imul_acc_execution, - power_stats->idiv_acc_execution); + wrapper->set_mem_ctrl_power(dram_reads, dram_writes, dram_pre); - wrapper->set_dp_accesses(power_stats->dp_acc_execution, - power_stats->dpmul_acc_execution, - power_stats->dpdiv_acc_execution); + if (aggregate_power_stats) { + power_stats->ialu_acc_execution += power_stats->get_ialu_accessess(1); + power_stats->imul24_acc_execution += power_stats->get_intmul24_accessess(1); + power_stats->imul32_acc_execution += power_stats->get_intmul32_accessess(1); + power_stats->imul_acc_execution += power_stats->get_intmul_accessess(1); + power_stats->idiv_acc_execution += power_stats->get_intdiv_accessess(1); + power_stats->dp_acc_execution += power_stats->get_dp_accessess(1); + power_stats->dpmul_acc_execution += power_stats->get_dpmul_accessess(1); + power_stats->dpdiv_acc_execution += power_stats->get_dpdiv_accessess(1); + power_stats->fp_acc_execution += power_stats->get_fp_accessess(1); + power_stats->fpmul_acc_execution += power_stats->get_fpmul_accessess(1); + power_stats->fpdiv_acc_execution += power_stats->get_fpdiv_accessess(1); + power_stats->sqrt_acc_execution += power_stats->get_sqrt_accessess(1); + power_stats->log_acc_execution += power_stats->get_log_accessess(1); + power_stats->sin_acc_execution += power_stats->get_sin_accessess(1); + power_stats->exp_acc_execution += power_stats->get_exp_accessess(1); + power_stats->tensor_acc_execution += power_stats->get_tensor_accessess(1); + power_stats->tex_acc_execution += power_stats->get_tex_accessess(1); + power_stats->tot_fpu_acc_execution += power_stats->get_tot_fpu_accessess(1); + power_stats->tot_sfu_acc_execution += power_stats->get_tot_sfu_accessess(1); + power_stats->tot_threads_acc_execution += + power_stats->get_tot_threads_kernel(1); + power_stats->tot_warps_acc_execution += + power_stats->get_tot_warps_kernel(1); - wrapper->set_fp_accesses(power_stats->fp_acc_execution, - power_stats->fpmul_acc_execution, - power_stats->fpdiv_acc_execution); + power_stats->sp_active_lanes_execution += + (power_stats->get_sp_active_lanes() * shdr_config->num_shader() * + shdr_config->gpgpu_num_sp_units); + power_stats->sfu_active_lanes_execution += + (power_stats->get_sfu_active_lanes() * shdr_config->num_shader() * + shdr_config->gpgpu_num_sp_units); - wrapper->set_trans_accesses(power_stats->sqrt_acc_execution, - power_stats->log_acc_execution, - power_stats->sin_acc_execution, - power_stats->exp_acc_execution); + wrapper->set_int_accesses( + power_stats->ialu_acc_execution, power_stats->imul24_acc_execution, + power_stats->imul32_acc_execution, power_stats->imul_acc_execution, + power_stats->idiv_acc_execution); - wrapper->set_tensor_accesses(power_stats->tensor_acc_execution); + wrapper->set_dp_accesses(power_stats->dp_acc_execution, + power_stats->dpmul_acc_execution, + power_stats->dpdiv_acc_execution); - wrapper->set_tex_accesses(power_stats->tex_acc_execution); + wrapper->set_fp_accesses(power_stats->fp_acc_execution, + power_stats->fpmul_acc_execution, + power_stats->fpdiv_acc_execution); - wrapper->set_exec_unit_power(power_stats->ialu_acc_execution, - power_stats->tot_fpu_acc_execution, - power_stats->tot_sfu_acc_execution); + wrapper->set_trans_accesses( + power_stats->sqrt_acc_execution, power_stats->log_acc_execution, + power_stats->sin_acc_execution, power_stats->exp_acc_execution); - wrapper->set_avg_active_threads((double)((double)power_stats->tot_threads_acc_execution / (double)power_stats->tot_warps_acc_execution)); + wrapper->set_tensor_accesses(power_stats->tensor_acc_execution); - // Average active lanes for sp and sfu pipelines - float avg_sp_active_lanes = - (power_stats->sp_active_lanes_execution) / shdr_config->num_shader() / shdr_config->gpgpu_num_sp_units / stat_sample_freq; - float avg_sfu_active_lanes = - (power_stats->sfu_active_lanes_execution) / shdr_config->num_shader() / shdr_config->gpgpu_num_sp_units / stat_sample_freq; - if(avg_sp_active_lanes >32.0 ) - avg_sp_active_lanes = 32.0; - if(avg_sfu_active_lanes >32.0 ) - avg_sfu_active_lanes = 32.0; - assert(avg_sp_active_lanes <= 32); - assert(avg_sfu_active_lanes <= 32); - wrapper->set_active_lanes_power(avg_sp_active_lanes, avg_sfu_active_lanes); - } - else{ - wrapper->set_int_accesses(power_stats->get_ialu_accessess(1), - power_stats->get_intmul24_accessess(1), - power_stats->get_intmul32_accessess(1), - power_stats->get_intmul_accessess(1), - power_stats->get_intdiv_accessess(1)); + wrapper->set_tex_accesses(power_stats->tex_acc_execution); - wrapper->set_dp_accesses(power_stats->get_dp_accessess(1), - power_stats->get_dpmul_accessess(1), - power_stats->get_dpdiv_accessess(1)); + wrapper->set_exec_unit_power(power_stats->ialu_acc_execution, + power_stats->tot_fpu_acc_execution, + power_stats->tot_sfu_acc_execution); - wrapper->set_fp_accesses(power_stats->get_fp_accessess(1), - power_stats->get_fpmul_accessess(1), - power_stats->get_fpdiv_accessess(1)); + wrapper->set_avg_active_threads( + (double)((double)power_stats->tot_threads_acc_execution / + (double)power_stats->tot_warps_acc_execution)); - wrapper->set_trans_accesses(power_stats->get_sqrt_accessess(1), - power_stats->get_log_accessess(1), - power_stats->get_sin_accessess(1), - power_stats->get_exp_accessess(1)); + // Average active lanes for sp and sfu pipelines + float avg_sp_active_lanes = + (power_stats->sp_active_lanes_execution) / shdr_config->num_shader() / + shdr_config->gpgpu_num_sp_units / stat_sample_freq; + float avg_sfu_active_lanes = + (power_stats->sfu_active_lanes_execution) / shdr_config->num_shader() / + shdr_config->gpgpu_num_sp_units / stat_sample_freq; + if (avg_sp_active_lanes > 32.0) avg_sp_active_lanes = 32.0; + if (avg_sfu_active_lanes > 32.0) avg_sfu_active_lanes = 32.0; + assert(avg_sp_active_lanes <= 32); + assert(avg_sfu_active_lanes <= 32); + wrapper->set_active_lanes_power(avg_sp_active_lanes, avg_sfu_active_lanes); + } else { + wrapper->set_int_accesses(power_stats->get_ialu_accessess(1), + power_stats->get_intmul24_accessess(1), + power_stats->get_intmul32_accessess(1), + power_stats->get_intmul_accessess(1), + power_stats->get_intdiv_accessess(1)); - wrapper->set_tensor_accesses(power_stats->get_tensor_accessess(1)); + wrapper->set_dp_accesses(power_stats->get_dp_accessess(1), + power_stats->get_dpmul_accessess(1), + power_stats->get_dpdiv_accessess(1)); - wrapper->set_tex_accesses(power_stats->get_tex_accessess(1)); + wrapper->set_fp_accesses(power_stats->get_fp_accessess(1), + power_stats->get_fpmul_accessess(1), + power_stats->get_fpdiv_accessess(1)); - wrapper->set_exec_unit_power(power_stats->get_tot_fpu_accessess(1), - power_stats->get_ialu_accessess(1), - power_stats->get_tot_sfu_accessess(1)); + wrapper->set_trans_accesses( + power_stats->get_sqrt_accessess(1), power_stats->get_log_accessess(1), + power_stats->get_sin_accessess(1), power_stats->get_exp_accessess(1)); - wrapper->set_avg_active_threads(power_stats->get_active_threads(1)); + wrapper->set_tensor_accesses(power_stats->get_tensor_accessess(1)); - // Average active lanes for sp and sfu pipelines - float avg_sp_active_lanes = - (power_stats->get_sp_active_lanes()) / stat_sample_freq; - float avg_sfu_active_lanes = - (power_stats->get_sfu_active_lanes()) / stat_sample_freq; - if(avg_sp_active_lanes >32.0 ) - avg_sp_active_lanes = 32.0; - if(avg_sfu_active_lanes >32.0 ) - avg_sfu_active_lanes = 32.0; - assert(avg_sp_active_lanes <= 32); - assert(avg_sfu_active_lanes <= 32); - wrapper->set_active_lanes_power(avg_sp_active_lanes, avg_sfu_active_lanes); - } + wrapper->set_tex_accesses(power_stats->get_tex_accessess(1)); - - double n_icnt_simt_to_mem = - (double) - (power_stats->get_icnt_simt_to_mem(1) - power_stats->noc_tr_kernel); // # flits from SIMT clusters - // to memory partitions - double n_icnt_mem_to_simt = - (double) - (power_stats->get_icnt_mem_to_simt(1)- power_stats->noc_rc_kernel); // # flits from memory - // partitions to SIMT clusters - if((power_simulation_mode == 2) && (accelwattch_hybrid_configuration[HW_NOC])) - wrapper->set_NoC_power(n_icnt_mem_to_simt + n_icnt_simt_to_mem); // Number of flits traversing the interconnect from Accel-Sim - else - wrapper->set_NoC_power(std::stod(hw_data[HW_NOC])); // Number of flits traversing the interconnect from HW - - wrapper->compute(); + wrapper->set_exec_unit_power(power_stats->get_tot_fpu_accessess(1), + power_stats->get_ialu_accessess(1), + power_stats->get_tot_sfu_accessess(1)); - wrapper->update_components_power(); + wrapper->set_avg_active_threads(power_stats->get_active_threads(1)); - wrapper->power_metrics_calculations(); + // Average active lanes for sp and sfu pipelines + float avg_sp_active_lanes = + (power_stats->get_sp_active_lanes()) / stat_sample_freq; + float avg_sfu_active_lanes = + (power_stats->get_sfu_active_lanes()) / stat_sample_freq; + if (avg_sp_active_lanes > 32.0) avg_sp_active_lanes = 32.0; + if (avg_sfu_active_lanes > 32.0) avg_sfu_active_lanes = 32.0; + assert(avg_sp_active_lanes <= 32); + assert(avg_sfu_active_lanes <= 32); + wrapper->set_active_lanes_power(avg_sp_active_lanes, avg_sfu_active_lanes); + } - wrapper->dump(); - power_stats->l1r_hits_kernel = power_stats->get_l1d_read_hits(1); - power_stats->l1r_misses_kernel = power_stats->get_l1d_read_misses(1); - power_stats->l1w_hits_kernel = power_stats->get_l1d_write_hits(1); - power_stats->l1w_misses_kernel = power_stats->get_l1d_write_misses(1); - power_stats->shared_accesses_kernel = power_stats->get_const_accessess(1); - power_stats->cc_accesses_kernel = power_stats->get_shmem_access(1); - power_stats->dram_rd_kernel = power_stats->get_dram_rd(1); - power_stats->dram_wr_kernel = power_stats->get_dram_wr(1); - power_stats->dram_pre_kernel = power_stats->get_dram_pre(1); - power_stats->l1i_hits_kernel = power_stats->get_inst_c_hits(1); - power_stats->l1i_misses_kernel = power_stats->get_inst_c_misses(1); - power_stats->l2r_hits_kernel = power_stats->get_l2_read_hits(1); - power_stats->l2r_misses_kernel = power_stats->get_l2_read_misses(1); - power_stats->l2w_hits_kernel = power_stats->get_l2_write_hits(1); - power_stats->l2w_misses_kernel = power_stats->get_l2_write_misses(1); - power_stats->noc_tr_kernel = power_stats->get_icnt_simt_to_mem(1); - power_stats->noc_rc_kernel = power_stats->get_icnt_mem_to_simt(1); + double n_icnt_simt_to_mem = + (double)(power_stats->get_icnt_simt_to_mem(1) - + power_stats->noc_tr_kernel); // # flits from SIMT clusters + // to memory partitions + double n_icnt_mem_to_simt = + (double)(power_stats->get_icnt_mem_to_simt(1) - + power_stats->noc_rc_kernel); // # flits from memory + // partitions to SIMT clusters + if ((power_simulation_mode == 2) && + (accelwattch_hybrid_configuration[HW_NOC])) + wrapper->set_NoC_power( + n_icnt_mem_to_simt + + n_icnt_simt_to_mem); // Number of flits traversing the interconnect + // from Accel-Sim + else + wrapper->set_NoC_power( + std::stod(hw_data[HW_NOC])); // Number of flits traversing the + // interconnect from HW + + wrapper->compute(); + + wrapper->update_components_power(); + + wrapper->power_metrics_calculations(); + wrapper->dump(); + power_stats->l1r_hits_kernel = power_stats->get_l1d_read_hits(1); + power_stats->l1r_misses_kernel = power_stats->get_l1d_read_misses(1); + power_stats->l1w_hits_kernel = power_stats->get_l1d_write_hits(1); + power_stats->l1w_misses_kernel = power_stats->get_l1d_write_misses(1); + power_stats->shared_accesses_kernel = power_stats->get_const_accessess(1); + power_stats->cc_accesses_kernel = power_stats->get_shmem_access(1); + power_stats->dram_rd_kernel = power_stats->get_dram_rd(1); + power_stats->dram_wr_kernel = power_stats->get_dram_wr(1); + power_stats->dram_pre_kernel = power_stats->get_dram_pre(1); + power_stats->l1i_hits_kernel = power_stats->get_inst_c_hits(1); + power_stats->l1i_misses_kernel = power_stats->get_inst_c_misses(1); + power_stats->l2r_hits_kernel = power_stats->get_l2_read_hits(1); + power_stats->l2r_misses_kernel = power_stats->get_l2_read_misses(1); + power_stats->l2w_hits_kernel = power_stats->get_l2_write_hits(1); + power_stats->l2w_misses_kernel = power_stats->get_l2_write_misses(1); + power_stats->noc_tr_kernel = power_stats->get_icnt_simt_to_mem(1); + power_stats->noc_rc_kernel = power_stats->get_icnt_mem_to_simt(1); - power_stats->clear(); + power_stats->clear(); }
\ No newline at end of file diff --git a/src/gpgpu-sim/power_interface.h b/src/gpgpu-sim/power_interface.h index 1a48894..3c043e6 100644 --- a/src/gpgpu-sim/power_interface.h +++ b/src/gpgpu-sim/power_interface.h @@ -1,16 +1,18 @@ -// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, Tayler Hetherington, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, Tayler +// Hetherington, Vijay Kandiah, Nikos Hardavellas, Mahmoud Khairy, Junrui Pan, +// Timothy G. Rogers The University of British Columbia, Northwestern +// University, Purdue University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -46,16 +48,18 @@ void mcpat_cycle(const gpgpu_sim_config &config, unsigned tot_cycle, unsigned cycle, unsigned tot_inst, unsigned inst, bool dvfs_enabled); -void calculate_hw_mcpat(const gpgpu_sim_config &config, - const shader_core_config *shdr_config, - class gpgpu_sim_wrapper *wrapper, - class power_stat_t *power_stats, unsigned stat_sample_freq, - unsigned tot_cycle, unsigned cycle, unsigned tot_inst, - unsigned inst, int power_simulation_mode, bool dvfs_enabled, - char* hwpowerfile, char* benchname, std::string executed_kernelname, - const bool *accelwattch_hybrid_configuration, bool aggregate_power_stats); +void calculate_hw_mcpat( + const gpgpu_sim_config &config, const shader_core_config *shdr_config, + class gpgpu_sim_wrapper *wrapper, class power_stat_t *power_stats, + unsigned stat_sample_freq, unsigned tot_cycle, unsigned cycle, + unsigned tot_inst, unsigned inst, int power_simulation_mode, + bool dvfs_enabled, char *hwpowerfile, char *benchname, + std::string executed_kernelname, + const bool *accelwattch_hybrid_configuration, bool aggregate_power_stats); -bool parse_hw_file(char* hwpowerfile, bool find_target_kernel, vector<string> &hw_data, char* benchname, std::string executed_kernelname); +bool parse_hw_file(char *hwpowerfile, bool find_target_kernel, + vector<string> &hw_data, char *benchname, + std::string executed_kernelname); void mcpat_reset_perf_count(class gpgpu_sim_wrapper *wrapper); diff --git a/src/gpgpu-sim/power_stat.cc b/src/gpgpu-sim/power_stat.cc index fd7a775..764652b 100644 --- a/src/gpgpu-sim/power_stat.cc +++ b/src/gpgpu-sim/power_stat.cc @@ -1,16 +1,18 @@ -// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, Tayler Hetherington, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, Tayler +// Hetherington, Vijay Kandiah, Nikos Hardavellas, Mahmoud Khairy, Junrui Pan, +// Timothy G. Rogers The University of British Columbia, Northwestern +// University, Purdue University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -55,60 +57,58 @@ power_mem_stat_t::power_mem_stat_t(const memory_config *mem_config, init(); } -void power_stat_t::clear(){ - for(unsigned i=0; i< NUM_STAT_IDX; ++i){ +void power_stat_t::clear() { + for (unsigned i = 0; i < NUM_STAT_IDX; ++i) { pwr_mem_stat->core_cache_stats[i].clear(); pwr_mem_stat->l2_cache_stats[i].clear(); - for(unsigned j=0; j<m_config->num_shader(); ++j){ - pwr_core_stat->m_pipeline_duty_cycle[i][j]=0; - pwr_core_stat->m_num_decoded_insn[i][j]=0; - pwr_core_stat->m_num_FPdecoded_insn[i][j]=0; - pwr_core_stat->m_num_INTdecoded_insn[i][j]=0; - pwr_core_stat->m_num_storequeued_insn[i][j]=0; - pwr_core_stat->m_num_loadqueued_insn[i][j]=0; - pwr_core_stat->m_num_tex_inst[i][j]=0; - pwr_core_stat->m_num_ialu_acesses[i][j]=0; - pwr_core_stat->m_num_fp_acesses[i][j]=0; - pwr_core_stat->m_num_imul_acesses[i][j]=0; - pwr_core_stat->m_num_imul24_acesses[i][j]=0; - pwr_core_stat->m_num_imul32_acesses[i][j]=0; - pwr_core_stat->m_num_fpmul_acesses[i][j]=0; - pwr_core_stat->m_num_idiv_acesses[i][j]=0; - pwr_core_stat->m_num_fpdiv_acesses[i][j]=0; - pwr_core_stat->m_num_dp_acesses[i][j]=0; - pwr_core_stat->m_num_dpmul_acesses[i][j]=0; - pwr_core_stat->m_num_dpdiv_acesses[i][j]=0; - pwr_core_stat->m_num_tensor_core_acesses[i][j]=0; - pwr_core_stat->m_num_const_acesses[i][j]=0; - pwr_core_stat->m_num_tex_acesses[i][j]=0; - pwr_core_stat->m_num_sp_acesses[i][j]=0; - pwr_core_stat->m_num_sfu_acesses[i][j]=0; - pwr_core_stat->m_num_sqrt_acesses[i][j]=0; - pwr_core_stat->m_num_log_acesses[i][j]=0; - pwr_core_stat->m_num_sin_acesses[i][j]=0; - pwr_core_stat->m_num_exp_acesses[i][j]=0; - pwr_core_stat->m_num_mem_acesses[i][j]=0; - pwr_core_stat->m_num_sp_committed[i][j]=0; - pwr_core_stat->m_num_sfu_committed[i][j]=0; - pwr_core_stat->m_num_mem_committed[i][j]=0; - pwr_core_stat->m_read_regfile_acesses[i][j]=0; - pwr_core_stat->m_write_regfile_acesses[i][j]=0; - pwr_core_stat->m_non_rf_operands[i][j]=0; - pwr_core_stat->m_active_sp_lanes[i][j]=0; - pwr_core_stat->m_active_sfu_lanes[i][j]=0; - pwr_core_stat->m_active_exu_threads[i][j]=0; - pwr_core_stat->m_active_exu_warps[i][j]=0; + for (unsigned j = 0; j < m_config->num_shader(); ++j) { + pwr_core_stat->m_pipeline_duty_cycle[i][j] = 0; + pwr_core_stat->m_num_decoded_insn[i][j] = 0; + pwr_core_stat->m_num_FPdecoded_insn[i][j] = 0; + pwr_core_stat->m_num_INTdecoded_insn[i][j] = 0; + pwr_core_stat->m_num_storequeued_insn[i][j] = 0; + pwr_core_stat->m_num_loadqueued_insn[i][j] = 0; + pwr_core_stat->m_num_tex_inst[i][j] = 0; + pwr_core_stat->m_num_ialu_acesses[i][j] = 0; + pwr_core_stat->m_num_fp_acesses[i][j] = 0; + pwr_core_stat->m_num_imul_acesses[i][j] = 0; + pwr_core_stat->m_num_imul24_acesses[i][j] = 0; + pwr_core_stat->m_num_imul32_acesses[i][j] = 0; + pwr_core_stat->m_num_fpmul_acesses[i][j] = 0; + pwr_core_stat->m_num_idiv_acesses[i][j] = 0; + pwr_core_stat->m_num_fpdiv_acesses[i][j] = 0; + pwr_core_stat->m_num_dp_acesses[i][j] = 0; + pwr_core_stat->m_num_dpmul_acesses[i][j] = 0; + pwr_core_stat->m_num_dpdiv_acesses[i][j] = 0; + pwr_core_stat->m_num_tensor_core_acesses[i][j] = 0; + pwr_core_stat->m_num_const_acesses[i][j] = 0; + pwr_core_stat->m_num_tex_acesses[i][j] = 0; + pwr_core_stat->m_num_sp_acesses[i][j] = 0; + pwr_core_stat->m_num_sfu_acesses[i][j] = 0; + pwr_core_stat->m_num_sqrt_acesses[i][j] = 0; + pwr_core_stat->m_num_log_acesses[i][j] = 0; + pwr_core_stat->m_num_sin_acesses[i][j] = 0; + pwr_core_stat->m_num_exp_acesses[i][j] = 0; + pwr_core_stat->m_num_mem_acesses[i][j] = 0; + pwr_core_stat->m_num_sp_committed[i][j] = 0; + pwr_core_stat->m_num_sfu_committed[i][j] = 0; + pwr_core_stat->m_num_mem_committed[i][j] = 0; + pwr_core_stat->m_read_regfile_acesses[i][j] = 0; + pwr_core_stat->m_write_regfile_acesses[i][j] = 0; + pwr_core_stat->m_non_rf_operands[i][j] = 0; + pwr_core_stat->m_active_sp_lanes[i][j] = 0; + pwr_core_stat->m_active_sfu_lanes[i][j] = 0; + pwr_core_stat->m_active_exu_threads[i][j] = 0; + pwr_core_stat->m_active_exu_warps[i][j] = 0; } for (unsigned j = 0; j < m_mem_config->m_n_mem; ++j) { - pwr_mem_stat->n_rd[i][j]=0; - pwr_mem_stat->n_wr[i][j]=0; - pwr_mem_stat->n_pre[i][j]=0; + pwr_mem_stat->n_rd[i][j] = 0; + pwr_mem_stat->n_wr[i][j] = 0; + pwr_mem_stat->n_pre[i][j] = 0; } } } - - void power_mem_stat_t::init() { shmem_access[CURRENT_STAT_IDX] = m_core_stats->gpgpu_n_shmem_bank_access; // Shared memory access @@ -174,17 +174,18 @@ void power_mem_stat_t::print(FILE *fout) const { unsigned total_mem_writes = 0; for (unsigned i = 0; i < m_config->m_n_mem; ++i) { total_mem_reads += n_rd[CURRENT_STAT_IDX][i]; - total_mem_writes += n_wr[CURRENT_STAT_IDX][i] + n_wr_WB[CURRENT_STAT_IDX][i]; + total_mem_writes += + n_wr[CURRENT_STAT_IDX][i] + n_wr_WB[CURRENT_STAT_IDX][i]; } fprintf(fout, "Total memory controller accesses: %u\n", total_mem_reads + total_mem_writes); fprintf(fout, "Total memory controller reads: %u\n", total_mem_reads); fprintf(fout, "Total memory controller writes: %u\n", total_mem_writes); - + // TODO: print_stats(require stream ID input) fprintf(fout, "Core cache stats:\n"); - core_cache_stats->print_stats(fout); + core_cache_stats->print_stats(fout, -1); fprintf(fout, "L2 cache stats:\n"); - l2_cache_stats->print_stats(fout); + l2_cache_stats->print_stats(fout, -1); } power_core_stat_t::power_core_stat_t(const shader_core_config *shader_config, @@ -204,165 +205,272 @@ void power_core_stat_t::print(FILE *fout) { // per core statistics fprintf(fout, "Power Metrics: \n"); for (unsigned i = 0; i < m_config->num_shader(); i++) { - fprintf(fout,"core %u:\n",i); - fprintf(fout,"\tpipeline duty cycle =%f\n",m_pipeline_duty_cycle[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal Deocded Instructions=%u\n",m_num_decoded_insn[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal FP Deocded Instructions=%u\n",m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal INT Deocded Instructions=%u\n",m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal LOAD Queued Instructions=%u\n",m_num_loadqueued_insn[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal STORE Queued Instructions=%u\n",m_num_storequeued_insn[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal IALU Acesses=%f\n",m_num_ialu_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal FP Acesses=%f\n",m_num_fp_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal DP Acesses=%f\n",m_num_dp_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal IMUL Acesses=%f\n",m_num_imul_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal IMUL24 Acesses=%f\n",m_num_imul24_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal IMUL32 Acesses=%f\n",m_num_imul32_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal IDIV Acesses=%f\n",m_num_idiv_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal FPMUL Acesses=%f\n",m_num_fpmul_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal DPMUL Acesses=%f\n",m_num_dpmul_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal SQRT Acesses=%f\n",m_num_sqrt_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal LOG Acesses=%f\n",m_num_log_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal SIN Acesses=%f\n",m_num_sin_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal EXP Acesses=%f\n",m_num_exp_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal FPDIV Acesses=%f\n",m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal DPDIV Acesses=%f\n",m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal TENSOR Acesses=%f\n",m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal CONST Acesses=%f\n",m_num_const_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal TEX Acesses=%f\n",m_num_tex_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal SFU Acesses=%f\n",m_num_sfu_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal SP Acesses=%f\n",m_num_sp_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal MEM Acesses=%f\n",m_num_mem_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal SFU Commissions=%u\n",m_num_sfu_committed[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal SP Commissions=%u\n",m_num_sp_committed[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal MEM Commissions=%u\n",m_num_mem_committed[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal REG Reads=%u\n",m_read_regfile_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal REG Writes=%u\n",m_write_regfile_acesses[CURRENT_STAT_IDX][i]); - fprintf(fout,"\tTotal NON REG=%u\n",m_non_rf_operands[CURRENT_STAT_IDX][i]); + fprintf(fout, "core %u:\n", i); + fprintf(fout, "\tpipeline duty cycle =%f\n", + m_pipeline_duty_cycle[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal Deocded Instructions=%u\n", + m_num_decoded_insn[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal FP Deocded Instructions=%u\n", + m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal INT Deocded Instructions=%u\n", + m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal LOAD Queued Instructions=%u\n", + m_num_loadqueued_insn[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal STORE Queued Instructions=%u\n", + m_num_storequeued_insn[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal IALU Acesses=%f\n", + m_num_ialu_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal FP Acesses=%f\n", + m_num_fp_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal DP Acesses=%f\n", + m_num_dp_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal IMUL Acesses=%f\n", + m_num_imul_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal IMUL24 Acesses=%f\n", + m_num_imul24_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal IMUL32 Acesses=%f\n", + m_num_imul32_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal IDIV Acesses=%f\n", + m_num_idiv_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal FPMUL Acesses=%f\n", + m_num_fpmul_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal DPMUL Acesses=%f\n", + m_num_dpmul_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal SQRT Acesses=%f\n", + m_num_sqrt_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal LOG Acesses=%f\n", + m_num_log_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal SIN Acesses=%f\n", + m_num_sin_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal EXP Acesses=%f\n", + m_num_exp_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal FPDIV Acesses=%f\n", + m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal DPDIV Acesses=%f\n", + m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal TENSOR Acesses=%f\n", + m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal CONST Acesses=%f\n", + m_num_const_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal TEX Acesses=%f\n", + m_num_tex_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal SFU Acesses=%f\n", + m_num_sfu_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal SP Acesses=%f\n", + m_num_sp_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal MEM Acesses=%f\n", + m_num_mem_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal SFU Commissions=%u\n", + m_num_sfu_committed[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal SP Commissions=%u\n", + m_num_sp_committed[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal MEM Commissions=%u\n", + m_num_mem_committed[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal REG Reads=%u\n", + m_read_regfile_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal REG Writes=%u\n", + m_write_regfile_acesses[CURRENT_STAT_IDX][i]); + fprintf(fout, "\tTotal NON REG=%u\n", + m_non_rf_operands[CURRENT_STAT_IDX][i]); } } void power_core_stat_t::init() { - m_pipeline_duty_cycle[CURRENT_STAT_IDX]=m_core_stats->m_pipeline_duty_cycle; - m_num_decoded_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_decoded_insn; - m_num_FPdecoded_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_FPdecoded_insn; - m_num_INTdecoded_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_INTdecoded_insn; - m_num_storequeued_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_storequeued_insn; - m_num_loadqueued_insn[CURRENT_STAT_IDX]=m_core_stats->m_num_loadqueued_insn; - m_num_ialu_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_ialu_acesses; - m_num_fp_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_fp_acesses; - m_num_imul_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_imul_acesses; - m_num_imul24_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_imul24_acesses; - m_num_imul32_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_imul32_acesses; - m_num_fpmul_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_fpmul_acesses; - m_num_idiv_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_idiv_acesses; - m_num_fpdiv_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_fpdiv_acesses; - m_num_dp_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_dp_acesses; - m_num_dpmul_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_dpmul_acesses; - m_num_dpdiv_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_dpdiv_acesses; - m_num_sp_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_sp_acesses; - m_num_sfu_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_sfu_acesses; - m_num_sqrt_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_sqrt_acesses; - m_num_log_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_log_acesses; - m_num_sin_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_sin_acesses; - m_num_exp_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_exp_acesses; - m_num_tensor_core_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_tensor_core_acesses; - m_num_const_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_const_acesses; - m_num_tex_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_tex_acesses; - m_num_mem_acesses[CURRENT_STAT_IDX]=m_core_stats->m_num_mem_acesses; - m_num_sp_committed[CURRENT_STAT_IDX]=m_core_stats->m_num_sp_committed; - m_num_sfu_committed[CURRENT_STAT_IDX]=m_core_stats->m_num_sfu_committed; - m_num_mem_committed[CURRENT_STAT_IDX]=m_core_stats->m_num_mem_committed; - m_read_regfile_acesses[CURRENT_STAT_IDX]=m_core_stats->m_read_regfile_acesses; - m_write_regfile_acesses[CURRENT_STAT_IDX]=m_core_stats->m_write_regfile_acesses; - m_non_rf_operands[CURRENT_STAT_IDX]=m_core_stats->m_non_rf_operands; - m_active_sp_lanes[CURRENT_STAT_IDX]=m_core_stats->m_active_sp_lanes; - m_active_sfu_lanes[CURRENT_STAT_IDX]=m_core_stats->m_active_sfu_lanes; - m_active_exu_threads[CURRENT_STAT_IDX]=m_core_stats->m_active_exu_threads; - m_active_exu_warps[CURRENT_STAT_IDX]=m_core_stats->m_active_exu_warps; - m_num_tex_inst[CURRENT_STAT_IDX]=m_core_stats->m_num_tex_inst; - - m_pipeline_duty_cycle[PREV_STAT_IDX]=(float*)calloc(m_config->num_shader(),sizeof(float)); - m_num_decoded_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); - m_num_FPdecoded_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); - m_num_INTdecoded_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); - m_num_storequeued_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); - m_num_loadqueued_insn[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); - m_num_tex_inst[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); - - m_num_ialu_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_fp_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_imul_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_imul24_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_imul32_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_fpmul_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_idiv_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_fpdiv_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_dp_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_dpmul_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_dpdiv_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_tensor_core_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_const_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_tex_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_sp_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_sfu_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_sqrt_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_log_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_sin_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_exp_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_mem_acesses[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_num_sp_committed[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); - m_num_sfu_committed[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); - m_num_mem_committed[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); - m_read_regfile_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); - m_write_regfile_acesses[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); - m_non_rf_operands[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); - m_active_sp_lanes[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); - m_active_sfu_lanes[PREV_STAT_IDX]=(unsigned *)calloc(m_config->num_shader(),sizeof(unsigned)); - m_active_exu_threads[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); - m_active_exu_warps[PREV_STAT_IDX]=(double *)calloc(m_config->num_shader(),sizeof(double)); + m_pipeline_duty_cycle[CURRENT_STAT_IDX] = m_core_stats->m_pipeline_duty_cycle; + m_num_decoded_insn[CURRENT_STAT_IDX] = m_core_stats->m_num_decoded_insn; + m_num_FPdecoded_insn[CURRENT_STAT_IDX] = m_core_stats->m_num_FPdecoded_insn; + m_num_INTdecoded_insn[CURRENT_STAT_IDX] = m_core_stats->m_num_INTdecoded_insn; + m_num_storequeued_insn[CURRENT_STAT_IDX] = + m_core_stats->m_num_storequeued_insn; + m_num_loadqueued_insn[CURRENT_STAT_IDX] = m_core_stats->m_num_loadqueued_insn; + m_num_ialu_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_ialu_acesses; + m_num_fp_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_fp_acesses; + m_num_imul_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_imul_acesses; + m_num_imul24_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_imul24_acesses; + m_num_imul32_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_imul32_acesses; + m_num_fpmul_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_fpmul_acesses; + m_num_idiv_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_idiv_acesses; + m_num_fpdiv_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_fpdiv_acesses; + m_num_dp_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_dp_acesses; + m_num_dpmul_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_dpmul_acesses; + m_num_dpdiv_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_dpdiv_acesses; + m_num_sp_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_sp_acesses; + m_num_sfu_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_sfu_acesses; + m_num_sqrt_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_sqrt_acesses; + m_num_log_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_log_acesses; + m_num_sin_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_sin_acesses; + m_num_exp_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_exp_acesses; + m_num_tensor_core_acesses[CURRENT_STAT_IDX] = + m_core_stats->m_num_tensor_core_acesses; + m_num_const_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_const_acesses; + m_num_tex_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_tex_acesses; + m_num_mem_acesses[CURRENT_STAT_IDX] = m_core_stats->m_num_mem_acesses; + m_num_sp_committed[CURRENT_STAT_IDX] = m_core_stats->m_num_sp_committed; + m_num_sfu_committed[CURRENT_STAT_IDX] = m_core_stats->m_num_sfu_committed; + m_num_mem_committed[CURRENT_STAT_IDX] = m_core_stats->m_num_mem_committed; + m_read_regfile_acesses[CURRENT_STAT_IDX] = + m_core_stats->m_read_regfile_acesses; + m_write_regfile_acesses[CURRENT_STAT_IDX] = + m_core_stats->m_write_regfile_acesses; + m_non_rf_operands[CURRENT_STAT_IDX] = m_core_stats->m_non_rf_operands; + m_active_sp_lanes[CURRENT_STAT_IDX] = m_core_stats->m_active_sp_lanes; + m_active_sfu_lanes[CURRENT_STAT_IDX] = m_core_stats->m_active_sfu_lanes; + m_active_exu_threads[CURRENT_STAT_IDX] = m_core_stats->m_active_exu_threads; + m_active_exu_warps[CURRENT_STAT_IDX] = m_core_stats->m_active_exu_warps; + m_num_tex_inst[CURRENT_STAT_IDX] = m_core_stats->m_num_tex_inst; + m_pipeline_duty_cycle[PREV_STAT_IDX] = + (float *)calloc(m_config->num_shader(), sizeof(float)); + m_num_decoded_insn[PREV_STAT_IDX] = + (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned)); + m_num_FPdecoded_insn[PREV_STAT_IDX] = + (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned)); + m_num_INTdecoded_insn[PREV_STAT_IDX] = + (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned)); + m_num_storequeued_insn[PREV_STAT_IDX] = + (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned)); + m_num_loadqueued_insn[PREV_STAT_IDX] = + (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned)); + m_num_tex_inst[PREV_STAT_IDX] = + (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned)); + m_num_ialu_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_fp_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_imul_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_imul24_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_imul32_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_fpmul_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_idiv_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_fpdiv_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_dp_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_dpmul_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_dpdiv_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_tensor_core_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_const_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_tex_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_sp_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_sfu_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_sqrt_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_log_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_sin_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_exp_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_mem_acesses[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_num_sp_committed[PREV_STAT_IDX] = + (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned)); + m_num_sfu_committed[PREV_STAT_IDX] = + (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned)); + m_num_mem_committed[PREV_STAT_IDX] = + (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned)); + m_read_regfile_acesses[PREV_STAT_IDX] = + (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned)); + m_write_regfile_acesses[PREV_STAT_IDX] = + (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned)); + m_non_rf_operands[PREV_STAT_IDX] = + (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned)); + m_active_sp_lanes[PREV_STAT_IDX] = + (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned)); + m_active_sfu_lanes[PREV_STAT_IDX] = + (unsigned *)calloc(m_config->num_shader(), sizeof(unsigned)); + m_active_exu_threads[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); + m_active_exu_warps[PREV_STAT_IDX] = + (double *)calloc(m_config->num_shader(), sizeof(double)); } void power_core_stat_t::save_stats() { for (unsigned i = 0; i < m_config->num_shader(); ++i) { - m_pipeline_duty_cycle[PREV_STAT_IDX][i]=m_pipeline_duty_cycle[CURRENT_STAT_IDX][i]; - m_num_decoded_insn[PREV_STAT_IDX][i]= m_num_decoded_insn[CURRENT_STAT_IDX][i]; - m_num_FPdecoded_insn[PREV_STAT_IDX][i]=m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]; - m_num_INTdecoded_insn[PREV_STAT_IDX][i]=m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]; - m_num_storequeued_insn[PREV_STAT_IDX][i]=m_num_storequeued_insn[CURRENT_STAT_IDX][i]; - m_num_loadqueued_insn[PREV_STAT_IDX][i]=m_num_loadqueued_insn[CURRENT_STAT_IDX][i]; - m_num_ialu_acesses[PREV_STAT_IDX][i]=m_num_ialu_acesses[CURRENT_STAT_IDX][i]; - m_num_fp_acesses[PREV_STAT_IDX][i]=m_num_fp_acesses[CURRENT_STAT_IDX][i]; - m_num_tex_inst[PREV_STAT_IDX][i]=m_num_tex_inst[CURRENT_STAT_IDX][i]; - m_num_imul_acesses[PREV_STAT_IDX][i]=m_num_imul_acesses[CURRENT_STAT_IDX][i]; - m_num_imul24_acesses[PREV_STAT_IDX][i]=m_num_imul24_acesses[CURRENT_STAT_IDX][i]; - m_num_imul32_acesses[PREV_STAT_IDX][i]=m_num_imul32_acesses[CURRENT_STAT_IDX][i]; - m_num_fpmul_acesses[PREV_STAT_IDX][i]=m_num_fpmul_acesses[CURRENT_STAT_IDX][i]; - m_num_idiv_acesses[PREV_STAT_IDX][i]=m_num_idiv_acesses[CURRENT_STAT_IDX][i]; - m_num_fpdiv_acesses[PREV_STAT_IDX][i]=m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]; - m_num_sp_acesses[PREV_STAT_IDX][i]=m_num_sp_acesses[CURRENT_STAT_IDX][i]; - m_num_sfu_acesses[PREV_STAT_IDX][i]=m_num_sfu_acesses[CURRENT_STAT_IDX][i]; - m_num_sqrt_acesses[PREV_STAT_IDX][i]=m_num_sqrt_acesses[CURRENT_STAT_IDX][i]; - m_num_log_acesses[PREV_STAT_IDX][i]=m_num_log_acesses[CURRENT_STAT_IDX][i]; - m_num_sin_acesses[PREV_STAT_IDX][i]=m_num_sin_acesses[CURRENT_STAT_IDX][i]; - m_num_exp_acesses[PREV_STAT_IDX][i]=m_num_exp_acesses[CURRENT_STAT_IDX][i]; - m_num_dp_acesses[PREV_STAT_IDX][i]=m_num_dp_acesses[CURRENT_STAT_IDX][i]; - m_num_dpmul_acesses[PREV_STAT_IDX][i]=m_num_dpmul_acesses[CURRENT_STAT_IDX][i]; - m_num_dpdiv_acesses[PREV_STAT_IDX][i]=m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]; - m_num_tensor_core_acesses[PREV_STAT_IDX][i]=m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]; - m_num_const_acesses[PREV_STAT_IDX][i]=m_num_const_acesses[CURRENT_STAT_IDX][i]; - m_num_tex_acesses[PREV_STAT_IDX][i]=m_num_tex_acesses[CURRENT_STAT_IDX][i]; - m_num_mem_acesses[PREV_STAT_IDX][i]=m_num_mem_acesses[CURRENT_STAT_IDX][i]; - m_num_sp_committed[PREV_STAT_IDX][i]=m_num_sp_committed[CURRENT_STAT_IDX][i]; - m_num_sfu_committed[PREV_STAT_IDX][i]=m_num_sfu_committed[CURRENT_STAT_IDX][i]; - m_num_mem_committed[PREV_STAT_IDX][i]=m_num_mem_committed[CURRENT_STAT_IDX][i]; - m_read_regfile_acesses[PREV_STAT_IDX][i]=m_read_regfile_acesses[CURRENT_STAT_IDX][i]; - m_write_regfile_acesses[PREV_STAT_IDX][i]=m_write_regfile_acesses[CURRENT_STAT_IDX][i]; - m_non_rf_operands[PREV_STAT_IDX][i]=m_non_rf_operands[CURRENT_STAT_IDX][i]; - m_active_sp_lanes[PREV_STAT_IDX][i]=m_active_sp_lanes[CURRENT_STAT_IDX][i]; - m_active_sfu_lanes[PREV_STAT_IDX][i]=m_active_sfu_lanes[CURRENT_STAT_IDX][i]; - m_active_exu_threads[PREV_STAT_IDX][i]=m_active_exu_threads[CURRENT_STAT_IDX][i]; - m_active_exu_warps[PREV_STAT_IDX][i]=m_active_exu_warps[CURRENT_STAT_IDX][i]; + m_pipeline_duty_cycle[PREV_STAT_IDX][i] = + m_pipeline_duty_cycle[CURRENT_STAT_IDX][i]; + m_num_decoded_insn[PREV_STAT_IDX][i] = + m_num_decoded_insn[CURRENT_STAT_IDX][i]; + m_num_FPdecoded_insn[PREV_STAT_IDX][i] = + m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]; + m_num_INTdecoded_insn[PREV_STAT_IDX][i] = + m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]; + m_num_storequeued_insn[PREV_STAT_IDX][i] = + m_num_storequeued_insn[CURRENT_STAT_IDX][i]; + m_num_loadqueued_insn[PREV_STAT_IDX][i] = + m_num_loadqueued_insn[CURRENT_STAT_IDX][i]; + m_num_ialu_acesses[PREV_STAT_IDX][i] = + m_num_ialu_acesses[CURRENT_STAT_IDX][i]; + m_num_fp_acesses[PREV_STAT_IDX][i] = m_num_fp_acesses[CURRENT_STAT_IDX][i]; + m_num_tex_inst[PREV_STAT_IDX][i] = m_num_tex_inst[CURRENT_STAT_IDX][i]; + m_num_imul_acesses[PREV_STAT_IDX][i] = + m_num_imul_acesses[CURRENT_STAT_IDX][i]; + m_num_imul24_acesses[PREV_STAT_IDX][i] = + m_num_imul24_acesses[CURRENT_STAT_IDX][i]; + m_num_imul32_acesses[PREV_STAT_IDX][i] = + m_num_imul32_acesses[CURRENT_STAT_IDX][i]; + m_num_fpmul_acesses[PREV_STAT_IDX][i] = + m_num_fpmul_acesses[CURRENT_STAT_IDX][i]; + m_num_idiv_acesses[PREV_STAT_IDX][i] = + m_num_idiv_acesses[CURRENT_STAT_IDX][i]; + m_num_fpdiv_acesses[PREV_STAT_IDX][i] = + m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]; + m_num_sp_acesses[PREV_STAT_IDX][i] = m_num_sp_acesses[CURRENT_STAT_IDX][i]; + m_num_sfu_acesses[PREV_STAT_IDX][i] = + m_num_sfu_acesses[CURRENT_STAT_IDX][i]; + m_num_sqrt_acesses[PREV_STAT_IDX][i] = + m_num_sqrt_acesses[CURRENT_STAT_IDX][i]; + m_num_log_acesses[PREV_STAT_IDX][i] = + m_num_log_acesses[CURRENT_STAT_IDX][i]; + m_num_sin_acesses[PREV_STAT_IDX][i] = + m_num_sin_acesses[CURRENT_STAT_IDX][i]; + m_num_exp_acesses[PREV_STAT_IDX][i] = + m_num_exp_acesses[CURRENT_STAT_IDX][i]; + m_num_dp_acesses[PREV_STAT_IDX][i] = m_num_dp_acesses[CURRENT_STAT_IDX][i]; + m_num_dpmul_acesses[PREV_STAT_IDX][i] = + m_num_dpmul_acesses[CURRENT_STAT_IDX][i]; + m_num_dpdiv_acesses[PREV_STAT_IDX][i] = + m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]; + m_num_tensor_core_acesses[PREV_STAT_IDX][i] = + m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]; + m_num_const_acesses[PREV_STAT_IDX][i] = + m_num_const_acesses[CURRENT_STAT_IDX][i]; + m_num_tex_acesses[PREV_STAT_IDX][i] = + m_num_tex_acesses[CURRENT_STAT_IDX][i]; + m_num_mem_acesses[PREV_STAT_IDX][i] = + m_num_mem_acesses[CURRENT_STAT_IDX][i]; + m_num_sp_committed[PREV_STAT_IDX][i] = + m_num_sp_committed[CURRENT_STAT_IDX][i]; + m_num_sfu_committed[PREV_STAT_IDX][i] = + m_num_sfu_committed[CURRENT_STAT_IDX][i]; + m_num_mem_committed[PREV_STAT_IDX][i] = + m_num_mem_committed[CURRENT_STAT_IDX][i]; + m_read_regfile_acesses[PREV_STAT_IDX][i] = + m_read_regfile_acesses[CURRENT_STAT_IDX][i]; + m_write_regfile_acesses[PREV_STAT_IDX][i] = + m_write_regfile_acesses[CURRENT_STAT_IDX][i]; + m_non_rf_operands[PREV_STAT_IDX][i] = + m_non_rf_operands[CURRENT_STAT_IDX][i]; + m_active_sp_lanes[PREV_STAT_IDX][i] = + m_active_sp_lanes[CURRENT_STAT_IDX][i]; + m_active_sfu_lanes[PREV_STAT_IDX][i] = + m_active_sfu_lanes[CURRENT_STAT_IDX][i]; + m_active_exu_threads[PREV_STAT_IDX][i] = + m_active_exu_threads[CURRENT_STAT_IDX][i]; + m_active_exu_warps[PREV_STAT_IDX][i] = + m_active_exu_warps[CURRENT_STAT_IDX][i]; } } @@ -389,12 +497,12 @@ power_stat_t::power_stat_t(const shader_core_config *shader_config, dram_rd_kernel = 0; dram_wr_kernel = 0; dram_pre_kernel = 0; - l1i_hits_kernel =0; - l1i_misses_kernel =0; - l2r_hits_kernel =0; - l2r_misses_kernel =0; - l2w_hits_kernel =0; - l2w_misses_kernel =0; + l1i_hits_kernel = 0; + l1i_misses_kernel = 0; + l2r_hits_kernel = 0; + l2r_misses_kernel = 0; + l2w_hits_kernel = 0; + l2w_misses_kernel = 0; noc_tr_kernel = 0; noc_rc_kernel = 0; diff --git a/src/gpgpu-sim/power_stat.h b/src/gpgpu-sim/power_stat.h index e2c3ed5..13f144a 100644 --- a/src/gpgpu-sim/power_stat.h +++ b/src/gpgpu-sim/power_stat.h @@ -1,16 +1,18 @@ -// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, Tayler Hetherington, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// Copyright (c) 2009-2021, Tor M. Aamodt, Ahmed El-Shafiey, Tayler +// Hetherington, Vijay Kandiah, Nikos Hardavellas, Mahmoud Khairy, Junrui Pan, +// Timothy G. Rogers The University of British Columbia, Northwestern +// University, Purdue University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -52,40 +54,40 @@ struct shader_core_power_stats_pod { unsigned *m_num_INTdecoded_insn[NUM_STAT_IDX]; // number of instructions committed // by this shader core - unsigned *m_num_storequeued_insn[NUM_STAT_IDX]; - unsigned *m_num_loadqueued_insn[NUM_STAT_IDX]; - unsigned *m_num_tex_inst[NUM_STAT_IDX]; - double *m_num_ialu_acesses[NUM_STAT_IDX]; - double *m_num_fp_acesses[NUM_STAT_IDX]; - double *m_num_imul_acesses[NUM_STAT_IDX]; - double *m_num_imul32_acesses[NUM_STAT_IDX]; - double *m_num_imul24_acesses[NUM_STAT_IDX]; - double *m_num_fpmul_acesses[NUM_STAT_IDX]; - double *m_num_idiv_acesses[NUM_STAT_IDX]; - double *m_num_fpdiv_acesses[NUM_STAT_IDX]; - double *m_num_dp_acesses[NUM_STAT_IDX]; - double *m_num_dpmul_acesses[NUM_STAT_IDX]; - double *m_num_dpdiv_acesses[NUM_STAT_IDX]; - double *m_num_sp_acesses[NUM_STAT_IDX]; - double *m_num_sfu_acesses[NUM_STAT_IDX]; - double *m_num_sqrt_acesses[NUM_STAT_IDX]; - double *m_num_log_acesses[NUM_STAT_IDX]; - double *m_num_sin_acesses[NUM_STAT_IDX]; - double *m_num_exp_acesses[NUM_STAT_IDX]; - double *m_num_tensor_core_acesses[NUM_STAT_IDX]; - double *m_num_const_acesses[NUM_STAT_IDX]; - double *m_num_tex_acesses[NUM_STAT_IDX]; - double *m_num_mem_acesses[NUM_STAT_IDX]; - unsigned *m_num_sp_committed[NUM_STAT_IDX]; - unsigned *m_num_sfu_committed[NUM_STAT_IDX]; - unsigned *m_num_mem_committed[NUM_STAT_IDX]; - unsigned *m_active_sp_lanes[NUM_STAT_IDX]; - unsigned *m_active_sfu_lanes[NUM_STAT_IDX]; - double *m_active_exu_threads[NUM_STAT_IDX]; - double *m_active_exu_warps[NUM_STAT_IDX]; - unsigned *m_read_regfile_acesses[NUM_STAT_IDX]; - unsigned *m_write_regfile_acesses[NUM_STAT_IDX]; - unsigned *m_non_rf_operands[NUM_STAT_IDX]; + unsigned *m_num_storequeued_insn[NUM_STAT_IDX]; + unsigned *m_num_loadqueued_insn[NUM_STAT_IDX]; + unsigned *m_num_tex_inst[NUM_STAT_IDX]; + double *m_num_ialu_acesses[NUM_STAT_IDX]; + double *m_num_fp_acesses[NUM_STAT_IDX]; + double *m_num_imul_acesses[NUM_STAT_IDX]; + double *m_num_imul32_acesses[NUM_STAT_IDX]; + double *m_num_imul24_acesses[NUM_STAT_IDX]; + double *m_num_fpmul_acesses[NUM_STAT_IDX]; + double *m_num_idiv_acesses[NUM_STAT_IDX]; + double *m_num_fpdiv_acesses[NUM_STAT_IDX]; + double *m_num_dp_acesses[NUM_STAT_IDX]; + double *m_num_dpmul_acesses[NUM_STAT_IDX]; + double *m_num_dpdiv_acesses[NUM_STAT_IDX]; + double *m_num_sp_acesses[NUM_STAT_IDX]; + double *m_num_sfu_acesses[NUM_STAT_IDX]; + double *m_num_sqrt_acesses[NUM_STAT_IDX]; + double *m_num_log_acesses[NUM_STAT_IDX]; + double *m_num_sin_acesses[NUM_STAT_IDX]; + double *m_num_exp_acesses[NUM_STAT_IDX]; + double *m_num_tensor_core_acesses[NUM_STAT_IDX]; + double *m_num_const_acesses[NUM_STAT_IDX]; + double *m_num_tex_acesses[NUM_STAT_IDX]; + double *m_num_mem_acesses[NUM_STAT_IDX]; + unsigned *m_num_sp_committed[NUM_STAT_IDX]; + unsigned *m_num_sfu_committed[NUM_STAT_IDX]; + unsigned *m_num_mem_committed[NUM_STAT_IDX]; + unsigned *m_active_sp_lanes[NUM_STAT_IDX]; + unsigned *m_active_sfu_lanes[NUM_STAT_IDX]; + double *m_active_exu_threads[NUM_STAT_IDX]; + double *m_active_exu_warps[NUM_STAT_IDX]; + unsigned *m_read_regfile_acesses[NUM_STAT_IDX]; + unsigned *m_write_regfile_acesses[NUM_STAT_IDX]; + unsigned *m_non_rf_operands[NUM_STAT_IDX]; }; class power_core_stat_t : public shader_core_power_stats_pod { @@ -96,7 +98,6 @@ class power_core_stat_t : public shader_core_power_stats_pod { void print(FILE *fout); void init(); void save_stats(); - private: shader_core_stats *m_core_stats; @@ -205,35 +206,37 @@ class power_stat_t { double get_total_inst(bool aggregate_stat) { double total_inst = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat) + if (aggregate_stat) total_inst += (pwr_core_stat->m_num_decoded_insn[CURRENT_STAT_IDX][i]); else total_inst += (pwr_core_stat->m_num_decoded_insn[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_decoded_insn[PREV_STAT_IDX][i]); + (pwr_core_stat->m_num_decoded_insn[PREV_STAT_IDX][i]); } return total_inst; } double get_total_int_inst(bool aggregate_stat) { double total_inst = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat) - total_inst += - (pwr_core_stat->m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]); - else + if (aggregate_stat) total_inst += - (pwr_core_stat->m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_INTdecoded_insn[PREV_STAT_IDX][i]); + (pwr_core_stat->m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]); + else + total_inst += + (pwr_core_stat->m_num_INTdecoded_insn[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_INTdecoded_insn[PREV_STAT_IDX][i]); } return total_inst; } double get_total_fp_inst(bool aggregate_stat) { double total_inst = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat) - total_inst += (pwr_core_stat->m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]); - else - total_inst += (pwr_core_stat->m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_FPdecoded_insn[PREV_STAT_IDX][i]); + if (aggregate_stat) + total_inst += + (pwr_core_stat->m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]); + else + total_inst += + (pwr_core_stat->m_num_FPdecoded_insn[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_FPdecoded_insn[PREV_STAT_IDX][i]); } return total_inst; } @@ -282,43 +285,45 @@ class power_stat_t { double get_committed_inst(bool aggregate_stat) { double total_inst = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat) - total_inst += (pwr_core_stat->m_num_mem_committed[CURRENT_STAT_IDX][i]) + - (pwr_core_stat->m_num_sfu_committed[CURRENT_STAT_IDX][i]) + - (pwr_core_stat->m_num_sp_committed[CURRENT_STAT_IDX][i]); + if (aggregate_stat) + total_inst += + (pwr_core_stat->m_num_mem_committed[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_sfu_committed[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_sp_committed[CURRENT_STAT_IDX][i]); else - total_inst += (pwr_core_stat->m_num_mem_committed[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_mem_committed[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_sfu_committed[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_sfu_committed[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_sp_committed[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_sp_committed[PREV_STAT_IDX][i]); + total_inst += + (pwr_core_stat->m_num_mem_committed[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_mem_committed[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_sfu_committed[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_sfu_committed[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_sp_committed[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_sp_committed[PREV_STAT_IDX][i]); } return total_inst; } double get_regfile_reads(bool aggregate_stat) { double total_inst = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat) - total_inst += - (pwr_core_stat->m_read_regfile_acesses[CURRENT_STAT_IDX][i]); + if (aggregate_stat) + total_inst += + (pwr_core_stat->m_read_regfile_acesses[CURRENT_STAT_IDX][i]); else total_inst += - (pwr_core_stat->m_read_regfile_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_read_regfile_acesses[PREV_STAT_IDX][i]); + (pwr_core_stat->m_read_regfile_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_read_regfile_acesses[PREV_STAT_IDX][i]); } return total_inst; } double get_regfile_writes(bool aggregate_stat) { double total_inst = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat) + if (aggregate_stat) total_inst += - (pwr_core_stat->m_write_regfile_acesses[CURRENT_STAT_IDX][i]); + (pwr_core_stat->m_write_regfile_acesses[CURRENT_STAT_IDX][i]); else total_inst += - (pwr_core_stat->m_write_regfile_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_write_regfile_acesses[PREV_STAT_IDX][i]); + (pwr_core_stat->m_write_regfile_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_write_regfile_acesses[PREV_STAT_IDX][i]); } return total_inst; } @@ -336,11 +341,11 @@ class power_stat_t { double get_non_regfile_operands(bool aggregate_stat) { double total_inst = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat) - total_inst += (pwr_core_stat->m_non_rf_operands[CURRENT_STAT_IDX][i]); + if (aggregate_stat) + total_inst += (pwr_core_stat->m_non_rf_operands[CURRENT_STAT_IDX][i]); else total_inst += (pwr_core_stat->m_non_rf_operands[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_non_rf_operands[PREV_STAT_IDX][i]); + (pwr_core_stat->m_non_rf_operands[PREV_STAT_IDX][i]); } return total_inst; } @@ -363,45 +368,49 @@ class power_stat_t { return total_inst; } - double get_sqrt_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) - total_inst+=(pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i]); - else - total_inst+=(pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_sqrt_acesses[PREV_STAT_IDX][i]); - } - return total_inst; + double get_sqrt_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) + total_inst += (pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i]); + else + total_inst += (pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_sqrt_acesses[PREV_STAT_IDX][i]); + } + return total_inst; } - double get_log_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) - total_inst+=(pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i]); - else - total_inst+=(pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_log_acesses[PREV_STAT_IDX][i]); - } - return total_inst; + double get_log_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) + total_inst += (pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i]); + else + total_inst += (pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_log_acesses[PREV_STAT_IDX][i]); + } + return total_inst; } - double get_sin_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) - total_inst+=(pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i]); - else - total_inst+=(pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_sin_acesses[PREV_STAT_IDX][i]); - } - return total_inst; + double get_sin_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) + total_inst += (pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i]); + else + total_inst += (pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_sin_acesses[PREV_STAT_IDX][i]); + } + return total_inst; } - double get_exp_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) - total_inst+=(pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i]); - else - total_inst+=(pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_exp_acesses[PREV_STAT_IDX][i]); - } - return total_inst; + double get_exp_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) + total_inst += (pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i]); + else + total_inst += (pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_exp_acesses[PREV_STAT_IDX][i]); + } + return total_inst; } double get_mem_accessess() { @@ -416,11 +425,11 @@ class power_stat_t { double get_intdiv_accessess(bool aggregate_stat) { double total_inst = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat) + if (aggregate_stat) total_inst += (pwr_core_stat->m_num_idiv_acesses[CURRENT_STAT_IDX][i]); else total_inst += (pwr_core_stat->m_num_idiv_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_idiv_acesses[PREV_STAT_IDX][i]); + (pwr_core_stat->m_num_idiv_acesses[PREV_STAT_IDX][i]); } return total_inst; } @@ -428,11 +437,12 @@ class power_stat_t { double get_fpdiv_accessess(bool aggregate_stat) { double total_inst = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat) + if (aggregate_stat) total_inst += (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]); - else - total_inst += (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_fpdiv_acesses[PREV_STAT_IDX][i]); + else + total_inst += + (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_fpdiv_acesses[PREV_STAT_IDX][i]); } return total_inst; } @@ -440,11 +450,13 @@ class power_stat_t { double get_intmul32_accessess(bool aggregate_stat) { double total_inst = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat) - total_inst += (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]); - else - total_inst += (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_imul32_acesses[PREV_STAT_IDX][i]); + if (aggregate_stat) + total_inst += + (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]); + else + total_inst += + (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_imul32_acesses[PREV_STAT_IDX][i]); } return total_inst; } @@ -452,118 +464,126 @@ class power_stat_t { double get_intmul24_accessess(bool aggregate_stat) { double total_inst = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat) - total_inst += (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]); - else - total_inst += (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_imul24_acesses[PREV_STAT_IDX][i]); + if (aggregate_stat) + total_inst += + (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]); + else + total_inst += + (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_imul24_acesses[PREV_STAT_IDX][i]); } return total_inst; } - double get_intmul_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) - total_inst+= (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]); - else - total_inst+= (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_imul_acesses[PREV_STAT_IDX][i]); - } - return total_inst; + double get_intmul_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) + total_inst += (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]); + else + total_inst += (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_imul_acesses[PREV_STAT_IDX][i]); + } + return total_inst; } - double get_fpmul_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) - total_inst += (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]); - else - total_inst += (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_fpmul_acesses[PREV_STAT_IDX][i]); + double get_fpmul_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) + total_inst += (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]); + else + total_inst += + (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_fpmul_acesses[PREV_STAT_IDX][i]); } return total_inst; } - double get_fp_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) - total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i]); - else - total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i]) - + double get_fp_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) + total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i]); + else + total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_fp_acesses[PREV_STAT_IDX][i]); } return total_inst; } - double get_dp_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) - total_inst += (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]); - else - total_inst += (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]) - + double get_dp_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) + total_inst += (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]); + else + total_inst += (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_dp_acesses[PREV_STAT_IDX][i]); } return total_inst; } - double get_dpmul_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) + double get_dpmul_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) total_inst += (pwr_core_stat->m_num_dpmul_acesses[CURRENT_STAT_IDX][i]); - else - total_inst += (pwr_core_stat->m_num_dpmul_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_dpmul_acesses[PREV_STAT_IDX][i]); + else + total_inst += + (pwr_core_stat->m_num_dpmul_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_dpmul_acesses[PREV_STAT_IDX][i]); } return total_inst; } - double get_dpdiv_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) + double get_dpdiv_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) total_inst += (pwr_core_stat->m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]); - else - total_inst += (pwr_core_stat->m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_dpdiv_acesses[PREV_STAT_IDX][i]); + else + total_inst += + (pwr_core_stat->m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_dpdiv_acesses[PREV_STAT_IDX][i]); } return total_inst; } - double get_tensor_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) - total_inst += (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]); - else - total_inst += (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_tensor_core_acesses[PREV_STAT_IDX][i]); + double get_tensor_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) + total_inst += + (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]); + else + total_inst += + (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_tensor_core_acesses[PREV_STAT_IDX][i]); } return total_inst; } - double get_const_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) - total_inst += pwr_core_stat->m_num_const_acesses[CURRENT_STAT_IDX][i]; - else - total_inst += (pwr_core_stat->m_num_const_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_const_acesses[PREV_STAT_IDX][i]); + double get_const_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) + total_inst += pwr_core_stat->m_num_const_acesses[CURRENT_STAT_IDX][i]; + else + total_inst += + (pwr_core_stat->m_num_const_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_const_acesses[PREV_STAT_IDX][i]); } return (total_inst); } - double get_tex_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) + double get_tex_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) total_inst += (pwr_core_stat->m_num_tex_acesses[CURRENT_STAT_IDX][i]); - else - total_inst += (pwr_core_stat->m_num_tex_acesses[CURRENT_STAT_IDX][i]) - + else + total_inst += (pwr_core_stat->m_num_tex_acesses[CURRENT_STAT_IDX][i]) - (pwr_core_stat->m_num_tex_acesses[PREV_STAT_IDX][i]); } return total_inst; @@ -589,23 +609,24 @@ class power_stat_t { m_config->gpgpu_num_sfu_units; } - float get_active_threads(bool aggregate_stat) { unsigned total_threads = 0; unsigned total_warps = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat){ - total_threads += (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]) ; + if (aggregate_stat) { + total_threads += + (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]); total_warps += (pwr_core_stat->m_active_exu_warps[CURRENT_STAT_IDX][i]); + } else { + total_threads += + (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_active_exu_threads[PREV_STAT_IDX][i]); + total_warps += + (pwr_core_stat->m_active_exu_warps[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_active_exu_warps[PREV_STAT_IDX][i]); } - else{ - total_threads += (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_active_exu_threads[PREV_STAT_IDX][i]); - total_warps += (pwr_core_stat->m_active_exu_warps[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_active_exu_warps[PREV_STAT_IDX][i]); - } } - if(total_warps != 0) + if (total_warps != 0) return (float)((float)total_threads / (float)total_warps); else return 0; @@ -614,98 +635,98 @@ class power_stat_t { unsigned long long get_tot_threads_kernel(bool aggregate_stat) { unsigned total_threads = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat){ - total_threads += (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]) ; + if (aggregate_stat) { + total_threads += + (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]); + } else { + total_threads += + (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_active_exu_threads[PREV_STAT_IDX][i]); } - else{ - total_threads += (pwr_core_stat->m_active_exu_threads[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_active_exu_threads[PREV_STAT_IDX][i]); - } } - return total_threads; + return total_threads; } unsigned long long get_tot_warps_kernel(bool aggregate_stat) { unsigned long long total_warps = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat){ + if (aggregate_stat) { total_warps += (pwr_core_stat->m_active_exu_warps[CURRENT_STAT_IDX][i]); + } else { + total_warps += + (pwr_core_stat->m_active_exu_warps[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_active_exu_warps[PREV_STAT_IDX][i]); } - else{ - total_warps += (pwr_core_stat->m_active_exu_warps[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_active_exu_warps[PREV_STAT_IDX][i]); - } } - return total_warps; + return total_warps; } - - double get_tot_fpu_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) - total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i])+ - (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]); + double get_tot_fpu_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) + total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]); else - total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_fp_acesses[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_dp_acesses[PREV_STAT_IDX][i]); + total_inst += (pwr_core_stat->m_num_fp_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_fp_acesses[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_dp_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_dp_acesses[PREV_STAT_IDX][i]); } - //total_inst += get_total_load_inst()+get_total_store_inst()+get_tex_inst(); + // total_inst += + // get_total_load_inst()+get_total_store_inst()+get_tex_inst(); return total_inst; } - - - double get_tot_sfu_accessess(bool aggregate_stat){ - double total_inst=0; - for(unsigned i=0; i<m_config->num_shader();i++){ - if(aggregate_stat) - total_inst += (pwr_core_stat->m_num_idiv_acesses[CURRENT_STAT_IDX][i])+ - (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i])+ - (pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i])+ - (pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i])+ - (pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i])+ - (pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i])+ - (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i])+ - (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i])+ - (pwr_core_stat->m_num_dpmul_acesses[CURRENT_STAT_IDX][i])+ - (pwr_core_stat->m_num_dpdiv_acesses[CURRENT_STAT_IDX][i])+ - (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]) + - (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i])+ - (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i])+ - (pwr_core_stat->m_num_tex_acesses[CURRENT_STAT_IDX][i]); - else - total_inst += (pwr_core_stat->m_num_idiv_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_idiv_acesses[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_imul32_acesses[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_sqrt_acesses[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_log_acesses[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_sin_acesses[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_exp_acesses[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_fpdiv_acesses[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_fpmul_acesses[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_dpmul_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_dpmul_acesses[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_dpdiv_acesses[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_imul24_acesses[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_imul_acesses[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_tensor_core_acesses[PREV_STAT_IDX][i]) + - (pwr_core_stat->m_num_tex_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_tex_acesses[PREV_STAT_IDX][i]); - + double get_tot_sfu_accessess(bool aggregate_stat) { + double total_inst = 0; + for (unsigned i = 0; i < m_config->num_shader(); i++) { + if (aggregate_stat) + total_inst += + (pwr_core_stat->m_num_idiv_acesses[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_dpmul_acesses[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]) + + (pwr_core_stat->m_num_tex_acesses[CURRENT_STAT_IDX][i]); + else + total_inst += + (pwr_core_stat->m_num_idiv_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_idiv_acesses[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_imul32_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_imul32_acesses[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_sqrt_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_sqrt_acesses[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_log_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_log_acesses[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_sin_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_sin_acesses[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_exp_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_exp_acesses[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_fpdiv_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_fpdiv_acesses[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_fpmul_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_fpmul_acesses[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_dpmul_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_dpmul_acesses[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_dpdiv_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_dpdiv_acesses[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_imul24_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_imul24_acesses[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_imul_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_imul_acesses[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_tensor_core_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_tensor_core_acesses[PREV_STAT_IDX][i]) + + (pwr_core_stat->m_num_tex_acesses[CURRENT_STAT_IDX][i]) - + (pwr_core_stat->m_num_tex_acesses[PREV_STAT_IDX][i]); } return total_inst; } @@ -713,11 +734,11 @@ class power_stat_t { double get_ialu_accessess(bool aggregate_stat) { double total_inst = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat) + if (aggregate_stat) total_inst += (pwr_core_stat->m_num_ialu_acesses[CURRENT_STAT_IDX][i]); - else + else total_inst += (pwr_core_stat->m_num_ialu_acesses[CURRENT_STAT_IDX][i]) - - (pwr_core_stat->m_num_ialu_acesses[PREV_STAT_IDX][i]); + (pwr_core_stat->m_num_ialu_acesses[PREV_STAT_IDX][i]); } return total_inst; } @@ -804,17 +825,16 @@ class power_stat_t { sizeof(access_type) / sizeof(enum mem_access_type); unsigned num_request_status = sizeof(request_status) / sizeof(enum cache_request_status); - if(aggregate_stat) + if (aggregate_stat) return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); + access_type, num_access_type, request_status, num_request_status)); else return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)) - - (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); + access_type, num_access_type, request_status, + num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)); } double get_inst_c_misses(bool aggregate_stat) { enum mem_access_type access_type[] = {INST_ACC_R}; @@ -823,46 +843,45 @@ class power_stat_t { sizeof(access_type) / sizeof(enum mem_access_type); unsigned num_request_status = sizeof(request_status) / sizeof(enum cache_request_status); - if(aggregate_stat) + if (aggregate_stat) return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); + access_type, num_access_type, request_status, num_request_status)); else return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)) - - (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); + access_type, num_access_type, request_status, + num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)); } double get_inst_c_hits(bool aggregate_stat) { - return (get_inst_c_accesses(aggregate_stat) - get_inst_c_misses(aggregate_stat)); + return (get_inst_c_accesses(aggregate_stat) - + get_inst_c_misses(aggregate_stat)); } double get_l1d_read_accesses(bool aggregate_stat) { enum mem_access_type access_type[] = {GLOBAL_ACC_R, LOCAL_ACC_R}; - enum cache_request_status request_status[] = {HIT, MISS, SECTOR_MISS}; + enum cache_request_status request_status[] = {HIT, MISS, SECTOR_MISS}; unsigned num_access_type = sizeof(access_type) / sizeof(enum mem_access_type); unsigned num_request_status = sizeof(request_status) / sizeof(enum cache_request_status); - if(aggregate_stat){ + if (aggregate_stat) { return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); - } - else{ + access_type, num_access_type, request_status, num_request_status)); + } else { return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)) - - (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); - } + access_type, num_access_type, request_status, + num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)); + } } double get_l1d_read_misses(bool aggregate_stat) { - return (get_l1d_read_accesses(aggregate_stat) - get_l1d_read_hits(aggregate_stat)); + return (get_l1d_read_accesses(aggregate_stat) - + get_l1d_read_hits(aggregate_stat)); } double get_l1d_read_hits(bool aggregate_stat) { enum mem_access_type access_type[] = {GLOBAL_ACC_R, LOCAL_ACC_R}; @@ -872,19 +891,17 @@ class power_stat_t { unsigned num_request_status = sizeof(request_status) / sizeof(enum cache_request_status); - if(aggregate_stat){ - return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); - } - else{ + if (aggregate_stat) { return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)) - - (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); - } + access_type, num_access_type, request_status, num_request_status)); + } else { + return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)); + } } double get_l1d_write_accesses(bool aggregate_stat) { enum mem_access_type access_type[] = {GLOBAL_ACC_W, LOCAL_ACC_W}; @@ -894,22 +911,21 @@ class power_stat_t { unsigned num_request_status = sizeof(request_status) / sizeof(enum cache_request_status); - if(aggregate_stat){ - return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); - } - else{ + if (aggregate_stat) { return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)) - - (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); - } + access_type, num_access_type, request_status, num_request_status)); + } else { + return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)); + } } double get_l1d_write_misses(bool aggregate_stat) { - return (get_l1d_write_accesses(aggregate_stat) - get_l1d_write_hits(aggregate_stat)); + return (get_l1d_write_accesses(aggregate_stat) - + get_l1d_write_hits(aggregate_stat)); } double get_l1d_write_hits(bool aggregate_stat) { enum mem_access_type access_type[] = {GLOBAL_ACC_W, LOCAL_ACC_W}; @@ -919,19 +935,17 @@ class power_stat_t { unsigned num_request_status = sizeof(request_status) / sizeof(enum cache_request_status); - if(aggregate_stat){ - return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); - } - else{ + if (aggregate_stat) { return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)) - - (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); - } + access_type, num_access_type, request_status, num_request_status)); + } else { + return (pwr_mem_stat->core_cache_stats[CURRENT_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)) - + (pwr_mem_stat->core_cache_stats[PREV_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)); + } } double get_cache_misses() { return get_l1d_read_misses(0) + get_constant_c_misses() + @@ -948,111 +962,107 @@ class power_stat_t { double get_shmem_access(bool aggregate_stat) { unsigned total_inst = 0; for (unsigned i = 0; i < m_config->num_shader(); i++) { - if(aggregate_stat) + if (aggregate_stat) total_inst += (pwr_mem_stat->shmem_access[CURRENT_STAT_IDX][i]); else total_inst += (pwr_mem_stat->shmem_access[CURRENT_STAT_IDX][i]) - - (pwr_mem_stat->shmem_access[PREV_STAT_IDX][i]); + (pwr_mem_stat->shmem_access[PREV_STAT_IDX][i]); } return total_inst; } - unsigned long long get_l2_read_accesses(bool aggregate_stat) { + unsigned long long get_l2_read_accesses(bool aggregate_stat) { enum mem_access_type access_type[] = { GLOBAL_ACC_R, LOCAL_ACC_R, CONST_ACC_R, TEXTURE_ACC_R, INST_ACC_R}; - enum cache_request_status request_status[] = {HIT, HIT_RESERVED, MISS, SECTOR_MISS}; + enum cache_request_status request_status[] = {HIT, HIT_RESERVED, MISS, + SECTOR_MISS}; unsigned num_access_type = sizeof(access_type) / sizeof(enum mem_access_type); unsigned num_request_status = sizeof(request_status) / sizeof(enum cache_request_status); - if(aggregate_stat){ - return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); - } - else{ + if (aggregate_stat) { return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)) - - (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); + access_type, num_access_type, request_status, num_request_status)); + } else { + return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)) - + (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)); } } unsigned long long get_l2_read_misses(bool aggregate_stat) { - return (get_l2_read_accesses(aggregate_stat) - get_l2_read_hits(aggregate_stat)); + return (get_l2_read_accesses(aggregate_stat) - + get_l2_read_hits(aggregate_stat)); } unsigned long long get_l2_read_hits(bool aggregate_stat) { - enum mem_access_type access_type[] = { + enum mem_access_type access_type[] = { GLOBAL_ACC_R, LOCAL_ACC_R, CONST_ACC_R, TEXTURE_ACC_R, INST_ACC_R}; - enum cache_request_status request_status[] = {HIT, HIT_RESERVED}; + enum cache_request_status request_status[] = {HIT, HIT_RESERVED}; unsigned num_access_type = sizeof(access_type) / sizeof(enum mem_access_type); unsigned num_request_status = sizeof(request_status) / sizeof(enum cache_request_status); - if(aggregate_stat){ - return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); - } - else{ + if (aggregate_stat) { return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)) - - (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); + access_type, num_access_type, request_status, num_request_status)); + } else { + return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)) - + (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)); } } unsigned long long get_l2_write_accesses(bool aggregate_stat) { enum mem_access_type access_type[] = {GLOBAL_ACC_W, LOCAL_ACC_W, L1_WRBK_ACC}; - enum cache_request_status request_status[] = {HIT, HIT_RESERVED, MISS, SECTOR_MISS}; + enum cache_request_status request_status[] = {HIT, HIT_RESERVED, MISS, + SECTOR_MISS}; unsigned num_access_type = sizeof(access_type) / sizeof(enum mem_access_type); unsigned num_request_status = sizeof(request_status) / sizeof(enum cache_request_status); - if(aggregate_stat){ + if (aggregate_stat) { return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); - } - else{ + access_type, num_access_type, request_status, num_request_status)); + } else { return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)) - - (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); + access_type, num_access_type, request_status, + num_request_status)) - + (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)); } } unsigned long long get_l2_write_misses(bool aggregate_stat) { - return (get_l2_write_accesses(aggregate_stat) - get_l2_write_hits(aggregate_stat)); + return (get_l2_write_accesses(aggregate_stat) - + get_l2_write_hits(aggregate_stat)); } unsigned long long get_l2_write_hits(bool aggregate_stat) { - enum mem_access_type access_type[] = {GLOBAL_ACC_W, LOCAL_ACC_W, + enum mem_access_type access_type[] = {GLOBAL_ACC_W, LOCAL_ACC_W, L1_WRBK_ACC}; enum cache_request_status request_status[] = {HIT, HIT_RESERVED}; unsigned num_access_type = sizeof(access_type) / sizeof(enum mem_access_type); unsigned num_request_status = sizeof(request_status) / sizeof(enum cache_request_status); - if(aggregate_stat){ + if (aggregate_stat) { return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); - } - else{ + access_type, num_access_type, request_status, num_request_status)); + } else { return (pwr_mem_stat->l2_cache_stats[CURRENT_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)) - - (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats( - access_type, num_access_type, request_status, - num_request_status)); + access_type, num_access_type, request_status, + num_request_status)) - + (pwr_mem_stat->l2_cache_stats[PREV_STAT_IDX].get_stats( + access_type, num_access_type, request_status, + num_request_status)); } } double get_dram_cmd() { @@ -1090,12 +1100,11 @@ class power_stat_t { double get_dram_pre(bool aggregate_stat) { unsigned total = 0; for (unsigned i = 0; i < m_mem_config->m_n_mem; ++i) { - if(aggregate_stat){ + if (aggregate_stat) { total += pwr_mem_stat->n_pre[CURRENT_STAT_IDX][i]; - } - else{ + } else { total += (pwr_mem_stat->n_pre[CURRENT_STAT_IDX][i] - - pwr_mem_stat->n_pre[PREV_STAT_IDX][i]); + pwr_mem_stat->n_pre[PREV_STAT_IDX][i]); } } return total; @@ -1103,12 +1112,11 @@ class power_stat_t { double get_dram_rd(bool aggregate_stat) { unsigned total = 0; for (unsigned i = 0; i < m_mem_config->m_n_mem; ++i) { - if(aggregate_stat){ + if (aggregate_stat) { total += pwr_mem_stat->n_rd[CURRENT_STAT_IDX][i]; - } - else{ + } else { total += (pwr_mem_stat->n_rd[CURRENT_STAT_IDX][i] - - pwr_mem_stat->n_rd[PREV_STAT_IDX][i]); + pwr_mem_stat->n_rd[PREV_STAT_IDX][i]); } } return total; @@ -1116,15 +1124,14 @@ class power_stat_t { double get_dram_wr(bool aggregate_stat) { unsigned total = 0; for (unsigned i = 0; i < m_mem_config->m_n_mem; ++i) { - if(aggregate_stat){ - total += pwr_mem_stat->n_wr[CURRENT_STAT_IDX][i] + - pwr_mem_stat->n_wr_WB[CURRENT_STAT_IDX][i]; - } - else{ - total += (pwr_mem_stat->n_wr[CURRENT_STAT_IDX][i] - - pwr_mem_stat->n_wr[PREV_STAT_IDX][i]) + - (pwr_mem_stat->n_wr_WB[CURRENT_STAT_IDX][i] - - pwr_mem_stat->n_wr_WB[PREV_STAT_IDX][i]); + if (aggregate_stat) { + total += pwr_mem_stat->n_wr[CURRENT_STAT_IDX][i] + + pwr_mem_stat->n_wr_WB[CURRENT_STAT_IDX][i]; + } else { + total += (pwr_mem_stat->n_wr[CURRENT_STAT_IDX][i] - + pwr_mem_stat->n_wr[PREV_STAT_IDX][i]) + + (pwr_mem_stat->n_wr_WB[CURRENT_STAT_IDX][i] - + pwr_mem_stat->n_wr_WB[PREV_STAT_IDX][i]); } } return total; @@ -1140,13 +1147,12 @@ class power_stat_t { unsigned long long get_icnt_simt_to_mem(bool aggregate_stat) { long total = 0; - for (unsigned i = 0; i < m_config->n_simt_clusters; ++i){ - if(aggregate_stat){ + for (unsigned i = 0; i < m_config->n_simt_clusters; ++i) { + if (aggregate_stat) { total += pwr_mem_stat->n_simt_to_mem[CURRENT_STAT_IDX][i]; - } - else{ + } else { total += (pwr_mem_stat->n_simt_to_mem[CURRENT_STAT_IDX][i] - - pwr_mem_stat->n_simt_to_mem[PREV_STAT_IDX][i]); + pwr_mem_stat->n_simt_to_mem[PREV_STAT_IDX][i]); } } return total; @@ -1155,13 +1161,13 @@ class power_stat_t { unsigned long long get_icnt_mem_to_simt(bool aggregate_stat) { long total = 0; for (unsigned i = 0; i < m_config->n_simt_clusters; ++i) { - if(aggregate_stat){ + if (aggregate_stat) { total += pwr_mem_stat->n_mem_to_simt[CURRENT_STAT_IDX][i]; } - - else{ + + else { total += (pwr_mem_stat->n_mem_to_simt[CURRENT_STAT_IDX][i] - - pwr_mem_stat->n_mem_to_simt[PREV_STAT_IDX][i]); + pwr_mem_stat->n_mem_to_simt[PREV_STAT_IDX][i]); } } return total; diff --git a/src/gpgpu-sim/shader.cc b/src/gpgpu-sim/shader.cc index c0161dd..7482e0e 100644 --- a/src/gpgpu-sim/shader.cc +++ b/src/gpgpu-sim/shader.cc @@ -1,17 +1,19 @@ // Copyright (c) 2009-2021, Tor M. Aamodt, Wilson W.L. Fung, Ali Bakhoda, -// George L. Yuan, Andrew Turner, Inderpreet Singh, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// George L. Yuan, Andrew Turner, Inderpreet Singh, Vijay Kandiah, Nikos +// Hardavellas, Mahmoud Khairy, Junrui Pan, Timothy G. Rogers The University of +// British Columbia, Northwestern University, Purdue University All rights +// reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -55,11 +57,11 @@ mem_fetch *shader_core_mem_fetch_allocator::alloc( new_addr_type addr, mem_access_type type, unsigned size, bool wr, - unsigned long long cycle) const { + unsigned long long cycle, unsigned long long streamID) const { mem_access_t access(type, addr, size, wr, m_memory_config->gpgpu_ctx); - mem_fetch *mf = - new mem_fetch(access, NULL, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, -1, - m_core_id, m_cluster_id, m_memory_config, cycle); + mem_fetch *mf = new mem_fetch( + access, NULL, streamID, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, -1, + m_core_id, m_cluster_id, m_memory_config, cycle); return mf; } @@ -68,12 +70,12 @@ mem_fetch *shader_core_mem_fetch_allocator::alloc( const mem_access_byte_mask_t &byte_mask, const mem_access_sector_mask_t §or_mask, unsigned size, bool wr, unsigned long long cycle, unsigned wid, unsigned sid, unsigned tpc, - mem_fetch *original_mf) const { + mem_fetch *original_mf, unsigned long long streamID) const { mem_access_t access(type, addr, size, wr, active_mask, byte_mask, sector_mask, m_memory_config->gpgpu_ctx); mem_fetch *mf = new mem_fetch( - access, NULL, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, wid, m_core_id, - m_cluster_id, m_memory_config, cycle, original_mf); + access, NULL, streamID, wr ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, wid, + m_core_id, m_cluster_id, m_memory_config, cycle, original_mf); return mf; } ///////////////////////////////////////////////////////////////////////////// @@ -106,7 +108,7 @@ void shader_core_ctx::create_front_pipeline() { m_pipeline_reg.push_back( register_set(m_config->pipe_widths[j], pipeline_stage_name_decode[j])); } - for (int j = 0; j < m_config->m_specialized_unit.size(); j++) { + for (unsigned j = 0; j < m_config->m_specialized_unit.size(); j++) { m_pipeline_reg.push_back( register_set(m_config->m_specialized_unit[j].id_oc_spec_reg_width, m_config->m_specialized_unit[j].name)); @@ -114,7 +116,7 @@ void shader_core_ctx::create_front_pipeline() { m_specilized_dispatch_reg.push_back( &m_pipeline_reg[m_pipeline_reg.size() - 1]); } - for (int j = 0; j < m_config->m_specialized_unit.size(); j++) { + for (unsigned j = 0; j < m_config->m_specialized_unit.size(); j++) { m_pipeline_reg.push_back( register_set(m_config->m_specialized_unit[j].oc_ex_spec_reg_width, m_config->m_specialized_unit[j].name)); @@ -139,7 +141,7 @@ void shader_core_ctx::create_front_pipeline() { if (m_config->gpgpu_num_int_units > 0) assert(m_config->gpgpu_num_sched_per_core == m_pipeline_reg[ID_OC_INT].get_size()); - for (int j = 0; j < m_config->m_specialized_unit.size(); j++) { + for (unsigned j = 0; j < m_config->m_specialized_unit.size(); j++) { if (m_config->m_specialized_unit[j].num_units > 0) assert(m_config->gpgpu_num_sched_per_core == m_config->m_specialized_unit[j].id_oc_spec_reg_width); @@ -160,7 +162,10 @@ void shader_core_ctx::create_front_pipeline() { } // m_icnt = new shader_memory_interface(this,cluster); - if (m_config->gpgpu_perfect_mem) { + if (m_memory_config->SST_mode) { + m_icnt = new sst_memory_interface( + this, static_cast<sst_simt_core_cluster *>(m_cluster)); + } else if (m_config->gpgpu_perfect_mem) { m_icnt = new perfect_memory_interface(this, m_cluster); } else { m_icnt = new shader_memory_interface(this, m_cluster); @@ -176,7 +181,7 @@ void shader_core_ctx::create_front_pipeline() { snprintf(name, STRSIZE, "L1I_%03d", m_sid); m_L1I = new read_only_cache(name, m_config->m_L1I_config, m_sid, get_shader_instruction_cache_id(), m_icnt, - IN_L1I_MISS_QUEUE); + IN_L1I_MISS_QUEUE, OTHER_GPU_CACHE, m_gpu); } void shader_core_ctx::create_schedulers() { @@ -186,20 +191,16 @@ void shader_core_ctx::create_schedulers() { // must currently occur after all inputs have been initialized. std::string sched_config = m_config->gpgpu_scheduler_string; const concrete_scheduler scheduler = - sched_config.find("lrr") != std::string::npos - ? CONCRETE_SCHEDULER_LRR - : sched_config.find("two_level_active") != std::string::npos - ? CONCRETE_SCHEDULER_TWO_LEVEL_ACTIVE - : sched_config.find("gto") != std::string::npos - ? CONCRETE_SCHEDULER_GTO - : sched_config.find("rrr") != std::string::npos - ? CONCRETE_SCHEDULER_RRR - : sched_config.find("old") != std::string::npos - ? CONCRETE_SCHEDULER_OLDEST_FIRST - : sched_config.find("warp_limiting") != - std::string::npos - ? CONCRETE_SCHEDULER_WARP_LIMITING - : NUM_CONCRETE_SCHEDULERS; + sched_config.find("lrr") != std::string::npos ? CONCRETE_SCHEDULER_LRR + : sched_config.find("two_level_active") != std::string::npos + ? CONCRETE_SCHEDULER_TWO_LEVEL_ACTIVE + : sched_config.find("gto") != std::string::npos ? CONCRETE_SCHEDULER_GTO + : sched_config.find("rrr") != std::string::npos ? CONCRETE_SCHEDULER_RRR + : sched_config.find("old") != std::string::npos + ? CONCRETE_SCHEDULER_OLDEST_FIRST + : sched_config.find("warp_limiting") != std::string::npos + ? CONCRETE_SCHEDULER_WARP_LIMITING + : NUM_CONCRETE_SCHEDULERS; assert(scheduler != NUM_CONCRETE_SCHEDULERS); for (unsigned i = 0; i < m_config->gpgpu_num_sched_per_core; i++) { @@ -449,7 +450,7 @@ void shader_core_ctx::create_exec_pipeline() { m_ldst_unit = new ldst_unit(m_icnt, m_mem_fetch_allocator, this, &m_operand_collector, m_scoreboard, m_config, - m_memory_config, m_stats, m_sid, m_tpc); + m_memory_config, m_stats, m_sid, m_tpc, m_gpu); m_fu.push_back(m_ldst_unit); m_dispatch_port.push_back(ID_OC_MEM); m_issue_port.push_back(OC_EX_MEM); @@ -480,14 +481,14 @@ shader_core_ctx::shader_core_ctx(class gpgpu_sim *gpu, m_config = config; m_memory_config = mem_config; m_stats = stats; - unsigned warp_size = config->warp_size; + // unsigned warp_size = config->warp_size; Issue_Prio = 0; m_sid = shader_id; m_tpc = tpc_id; - if(get_gpu()->get_config().g_power_simulation_enabled){ - scaling_coeffs = get_gpu()->get_scaling_coeffs(); + if (get_gpu()->get_config().g_power_simulation_enabled) { + scaling_coeffs = get_gpu()->get_scaling_coeffs(); } m_last_inst_gpu_sim_cycle = 0; @@ -531,7 +532,6 @@ void shader_core_ctx::reinit(unsigned start_thread, unsigned end_thread, void shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread, unsigned end_thread, unsigned ctaid, int cta_size, kernel_info_t &kernel) { - // address_type start_pc = next_pc(start_thread); unsigned kernel_id = kernel.get_uid(); if (m_config->model == POST_DOMINATOR) { @@ -570,7 +570,8 @@ void shader_core_ctx::init_warps(unsigned cta_id, unsigned start_thread, start_pc = pc; } - m_warp[i]->init(start_pc, cta_id, i, active_threads, m_dynamic_warp_id); + m_warp[i]->init(start_pc, cta_id, i, active_threads, m_dynamic_warp_id, + kernel.get_streamID()); ++m_dynamic_warp_id; m_not_completed += n_active; ++m_active_warps; @@ -641,7 +642,8 @@ void shader_core_stats::print(FILE *fout) const { fprintf(fout, "gpgpu_n_param_mem_insn = %d\n", gpgpu_n_param_insn); fprintf(fout, "gpgpu_n_shmem_bkconflict = %d\n", gpgpu_n_shmem_bkconflict); - fprintf(fout, "gpgpu_n_cache_bkconflict = %d\n", gpgpu_n_cache_bkconflict); + fprintf(fout, "gpgpu_n_l1cache_bkconflict = %d\n", + gpgpu_n_l1cache_bkconflict); fprintf(fout, "gpgpu_n_intrawarp_mshr_merge = %d\n", gpgpu_n_intrawarp_mshr_merge); @@ -839,8 +841,8 @@ void shader_core_stats::visualizer_print(gzFile visualizer_file) { gzprintf(visualizer_file, "\n"); // overall cache miss rates - gzprintf(visualizer_file, "gpgpu_n_cache_bkconflict: %d\n", - gpgpu_n_cache_bkconflict); + gzprintf(visualizer_file, "gpgpu_n_l1cache_bkconflict: %d\n", + gpgpu_n_l1cache_bkconflict); gzprintf(visualizer_file, "gpgpu_n_shmem_bkconflict: %d\n", gpgpu_n_shmem_bkconflict); @@ -893,7 +895,9 @@ void shader_core_ctx::decode() { m_warp[m_inst_fetch_buffer.m_warp_id]->inc_inst_in_pipeline(); if (pI1) { m_stats->m_num_decoded_insn[m_sid]++; - if ((pI1->oprnd_type == INT_OP) || (pI1->oprnd_type == UN_OP)) { //these counters get added up in mcPat to compute scheduler power + if ((pI1->oprnd_type == INT_OP) || + (pI1->oprnd_type == UN_OP)) { // these counters get added up in mcPat + // to compute scheduler power m_stats->m_num_INTdecoded_insn[m_sid]++; } else if (pI1->oprnd_type == FP_OP) { m_stats->m_num_FPdecoded_insn[m_sid]++; @@ -904,7 +908,9 @@ void shader_core_ctx::decode() { m_warp[m_inst_fetch_buffer.m_warp_id]->ibuffer_fill(1, pI2); m_warp[m_inst_fetch_buffer.m_warp_id]->inc_inst_in_pipeline(); m_stats->m_num_decoded_insn[m_sid]++; - if ((pI1->oprnd_type == INT_OP) || (pI1->oprnd_type == UN_OP)) { //these counters get added up in mcPat to compute scheduler power + if ((pI1->oprnd_type == INT_OP) || + (pI1->oprnd_type == UN_OP)) { // these counters get added up in + // mcPat to compute scheduler power m_stats->m_num_INTdecoded_insn[m_sid]++; } else if (pI2->oprnd_type == FP_OP) { m_stats->m_num_FPdecoded_insn[m_sid]++; @@ -950,7 +956,8 @@ void shader_core_ctx::fetch() { m_threadState[tid].m_active = false; unsigned cta_id = m_warp[warp_id]->get_cta_id(); if (m_thread[tid] == NULL) { - register_cta_thread_exit(cta_id, m_kernel); + register_cta_thread_exit(cta_id, + m_warp[warp_id]->get_kernel_info()); } else { register_cta_thread_exit(cta_id, &(m_thread[tid]->get_kernel())); @@ -982,16 +989,15 @@ void shader_core_ctx::fetch() { // mem_fetch *mf = m_mem_fetch_allocator->alloc() mem_access_t acc(INST_ACC_R, ppc, nbytes, false, m_gpu->gpgpu_ctx); mem_fetch *mf = new mem_fetch( - acc, NULL /*we don't have an instruction yet*/, READ_PACKET_SIZE, - warp_id, m_sid, m_tpc, m_memory_config, + acc, NULL, m_warp[warp_id]->get_kernel_info()->get_streamID(), + READ_PACKET_SIZE, warp_id, m_sid, m_tpc, m_memory_config, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle); std::list<cache_event> events; enum cache_request_status status; - if (m_config->perfect_inst_const_cache){ + if (m_config->perfect_inst_const_cache) { status = HIT; shader_cache_access_log(m_sid, INSTRUCTION, 0); - } - else + } else status = m_L1I->access( (new_addr_type)ppc, mf, m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle, events); @@ -1038,13 +1044,31 @@ void shader_core_ctx::issue_warp(register_set &pipe_reg_set, m_warp[warp_id]->ibuffer_free(); assert(next_inst->valid()); **pipe_reg = *next_inst; // static instruction information - (*pipe_reg)->issue(active_mask, warp_id, - m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, - m_warp[warp_id]->get_dynamic_warp_id(), - sch_id); // dynamic instruction information + (*pipe_reg)->issue( + active_mask, warp_id, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle, + m_warp[warp_id]->get_dynamic_warp_id(), sch_id, + m_warp[warp_id]->get_streamID()); // dynamic instruction information m_stats->shader_cycle_distro[2 + (*pipe_reg)->active_count()]++; func_exec_inst(**pipe_reg); + // Add LDGSTS instructions into a buffer + unsigned int ldgdepbar_id = m_warp[warp_id]->m_ldgdepbar_id; + if (next_inst->m_is_ldgsts) { + if (m_warp[warp_id]->m_ldgdepbar_buf.size() == ldgdepbar_id + 1) { + m_warp[warp_id]->m_ldgdepbar_buf[ldgdepbar_id].push_back(*next_inst); + } else { + assert(m_warp[warp_id]->m_ldgdepbar_buf.size() < ldgdepbar_id + 1); + std::vector<warp_inst_t> l; + l.push_back(*next_inst); + m_warp[warp_id]->m_ldgdepbar_buf.push_back(l); + } + // If the mask of the instruction is all 0, then the address is also 0, + // so that there's no need to check through the writeback + if (next_inst->get_active_mask() == 0) { + (m_warp[warp_id]->m_ldgdepbar_buf.back()).back().pc = -1; + } + } + if (next_inst->op == BARRIER_OP) { m_warp[warp_id]->store_info_of_last_inst_at_barrier(*pipe_reg); m_barriers.warp_reaches_barrier(m_warp[warp_id]->get_cta_id(), warp_id, @@ -1052,6 +1076,47 @@ void shader_core_ctx::issue_warp(register_set &pipe_reg_set, } else if (next_inst->op == MEMORY_BARRIER_OP) { m_warp[warp_id]->set_membar(); + } else if (next_inst->m_is_ldgdepbar) { // Add for LDGDEPBAR + m_warp[warp_id]->m_ldgdepbar_id++; + // If there are no added LDGSTS, insert an empty vector + if (m_warp[warp_id]->m_ldgdepbar_buf.size() != ldgdepbar_id + 1) { + assert(m_warp[warp_id]->m_ldgdepbar_buf.size() < ldgdepbar_id + 1); + std::vector<warp_inst_t> l; + m_warp[warp_id]->m_ldgdepbar_buf.push_back(l); + } + } else if (next_inst->m_is_depbar) { // Add for DEPBAR + // Set to true immediately when a DEPBAR instruction is met + m_warp[warp_id]->m_waiting_ldgsts = true; + m_warp[warp_id]->m_depbar_group = + next_inst->m_depbar_group_no; // set in trace_driven.cc + + // Record the last group that's possbily being monitored by this DEPBAR + // instr + m_warp[warp_id]->m_depbar_start_id = m_warp[warp_id]->m_ldgdepbar_id - 1; + + // Record the last group that's actually being monitored by this DEPBAR + // instr + unsigned int end_group = + m_warp[warp_id]->m_ldgdepbar_id - m_warp[warp_id]->m_depbar_group; + + // Check for the case that the LDGSTSs monitored have finished when + // encountering the DEPBAR instruction + bool done_flag = true; + for (int i = 0; i < end_group; i++) { + for (int j = 0; j < m_warp[warp_id]->m_ldgdepbar_buf[i].size(); j++) { + if (m_warp[warp_id]->m_ldgdepbar_buf[i][j].pc != -1) { + done_flag = false; + goto UpdateDEPBAR; + } + } + } + + UpdateDEPBAR: + if (done_flag) { + if (m_warp[warp_id]->m_waiting_ldgsts) { + m_warp[warp_id]->m_waiting_ldgsts = false; + } + } } updateSIMTStack(warp_id, *pipe_reg); @@ -1128,11 +1193,12 @@ void scheduler_unit::order_rrr( if (m_num_issued_last_cycle > 0 || warp(m_current_turn_warp).done_exit() || warp(m_current_turn_warp).waiting()) { std::vector<shd_warp_t *>::const_iterator iter = - (last_issued_from_input == input_list.end()) ? - input_list.begin() : last_issued_from_input + 1; + (last_issued_from_input == input_list.end()) + ? input_list.begin() + : last_issued_from_input + 1; for (unsigned count = 0; count < num_warps_to_add; ++iter, ++count) { if (iter == input_list.end()) { - iter = input_list.begin(); + iter = input_list.begin(); } unsigned warp_id = (*iter)->get_warp_id(); if (!(*iter)->done_exit() && !(*iter)->waiting()) { @@ -1644,7 +1710,7 @@ void swl_scheduler::order_warps() { } void shader_core_ctx::read_operands() { - for (int i = 0; i < m_config->reg_file_port_throughput; ++i) + for (unsigned int i = 0; i < m_config->reg_file_port_throughput; ++i) m_operand_collector.step(); } @@ -1795,12 +1861,55 @@ void ldst_unit::get_L1T_sub_stats(struct cache_sub_stats &css) const { if (m_L1T) m_L1T->get_sub_stats(css); } +// Add this function to unset depbar +void shader_core_ctx::unset_depbar(const warp_inst_t &inst) { + bool done_flag = true; + unsigned int end_group = m_warp[inst.warp_id()]->m_depbar_start_id == 0 + ? m_warp[inst.warp_id()]->m_ldgdepbar_buf.size() + : (m_warp[inst.warp_id()]->m_depbar_start_id - + m_warp[inst.warp_id()]->m_depbar_group + 1); + + if (inst.m_is_ldgsts) { + for (int i = 0; i < m_warp[inst.warp_id()]->m_ldgdepbar_buf.size(); i++) { + for (int j = 0; j < m_warp[inst.warp_id()]->m_ldgdepbar_buf[i].size(); + j++) { + if (m_warp[inst.warp_id()]->m_ldgdepbar_buf[i][j].pc == inst.pc) { + // Handle the case that same pc results in multiple LDGSTS + // instructions + if (m_warp[inst.warp_id()]->m_ldgdepbar_buf[i][j].get_addr(0) == + inst.get_addr(0)) { + m_warp[inst.warp_id()]->m_ldgdepbar_buf[i][j].pc = -1; + goto DoneWB; + } + } + } + } + + DoneWB: + for (int i = 0; i < end_group; i++) { + for (int j = 0; j < m_warp[inst.warp_id()]->m_ldgdepbar_buf[i].size(); + j++) { + if (m_warp[inst.warp_id()]->m_ldgdepbar_buf[i][j].pc != -1) { + done_flag = false; + goto UpdateDEPBAR; + } + } + } + + UpdateDEPBAR: + if (done_flag) { + if (m_warp[inst.warp_id()]->m_waiting_ldgsts) { + m_warp[inst.warp_id()]->m_waiting_ldgsts = false; + } + } + } +} + void shader_core_ctx::warp_inst_complete(const warp_inst_t &inst) { #if 0 printf("[warp_inst_complete] uid=%u core=%u warp=%u pc=%#x @ time=%llu \n", inst.get_uid(), m_sid, inst.warp_id(), inst.pc, m_gpu->gpu_tot_sim_cycle + m_gpu->gpu_sim_cycle); #endif - if (inst.op_pipe == SP__OP) m_stats->m_num_sp_committed[m_sid]++; else if (inst.op_pipe == SFU__OP) @@ -1879,6 +1988,7 @@ bool ldst_unit::shared_cycle(warp_inst_t &inst, mem_stage_stall_type &rc_fail, if (stall) { fail_type = S_MEM; rc_fail = BK_CONF; + m_stats->gpgpu_n_shmem_bkconflict++; } else rc_fail = NO_RC_FAIL; return !stall; @@ -1905,6 +2015,14 @@ mem_stage_stall_type ldst_unit::process_cache_access( if (inst.is_load()) { for (unsigned r = 0; r < MAX_OUTPUT_VALUES; r++) if (inst.out[r] > 0) m_pending_writes[inst.warp_id()][inst.out[r]]--; + + // release LDGSTS + if (inst.m_is_ldgsts) { + m_pending_ldgsts[inst.warp_id()][inst.pc][inst.get_addr(0)]--; + if (m_pending_ldgsts[inst.warp_id()][inst.pc][inst.get_addr(0)] == 0) { + m_core->unset_depbar(inst); + } + } } if (!write_sent) delete mf; } else if (status == RESERVATION_FAIL) { @@ -1947,7 +2065,7 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue_l1cache( if (inst.accessq_empty()) return result; if (m_config->m_L1D_config.l1_latency > 0) { - for (int j = 0; j < m_config->m_L1D_config.l1_banks; + for (unsigned int j = 0; j < m_config->m_L1D_config.l1_banks; j++) { // We can handle at max l1_banks reqs per cycle if (inst.accessq_empty()) return result; @@ -1976,6 +2094,7 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue_l1cache( inst.accessq_pop_back(); } else { result = BK_CONF; + m_stats->gpgpu_n_l1cache_bkconflict++; delete mf; break; // do not try again, just break from the loop and try the next // cycle @@ -2000,7 +2119,7 @@ mem_stage_stall_type ldst_unit::process_memory_access_queue_l1cache( } void ldst_unit::L1_latency_queue_cycle() { - for (int j = 0; j < m_config->m_L1D_config.l1_banks; j++) { + for (unsigned int j = 0; j < m_config->m_L1D_config.l1_banks; j++) { if ((l1_latency_queue[j][0]) != NULL) { mem_fetch *mf_next = l1_latency_queue[j][0]; std::list<cache_event> events; @@ -2032,6 +2151,18 @@ void ldst_unit::L1_latency_queue_cycle() { m_core->warp_inst_complete(mf_next->get_inst()); } } + + // release LDGSTS + if (mf_next->get_inst().m_is_ldgsts) { + m_pending_ldgsts[mf_next->get_inst().warp_id()] + [mf_next->get_inst().pc] + [mf_next->get_inst().get_addr(0)]--; + if (m_pending_ldgsts[mf_next->get_inst().warp_id()] + [mf_next->get_inst().pc] + [mf_next->get_inst().get_addr(0)] == 0) { + m_core->unset_depbar(mf_next->get_inst()); + } + } } // For write hit in WB policy @@ -2091,10 +2222,12 @@ bool ldst_unit::constant_cycle(warp_inst_t &inst, mem_stage_stall_type &rc_fail, mem_stage_stall_type fail; if (m_config->perfect_inst_const_cache) { fail = NO_RC_FAIL; + unsigned access_count = inst.accessq_count(); while (inst.accessq_count() > 0) inst.accessq_pop_back(); if (inst.is_load()) { for (unsigned r = 0; r < MAX_OUTPUT_VALUES; r++) - if (inst.out[r] > 0) m_pending_writes[inst.warp_id()][inst.out[r]]--; + if (inst.out[r] > 0) + m_pending_writes[inst.warp_id()][inst.out[r]] -= access_count; } } else { fail = process_memory_access_queue(m_L1C, inst); @@ -2151,7 +2284,15 @@ bool ldst_unit::memory_cycle(warp_inst_t &inst, inst.is_store() ? WRITE_PACKET_SIZE : READ_PACKET_SIZE; unsigned size = access.get_size() + control_size; // printf("Interconnect:Addr: %x, size=%d\n",access.get_addr(),size); - if (m_icnt->full(size, inst.is_store() || inst.isatomic())) { + if (m_memory_config->SST_mode && + (static_cast<sst_memory_interface *>(m_icnt)->full( + size, inst.is_store() || inst.isatomic(), access.get_type()))) { + // SST need mf type here + // Cast it to sst_memory_interface pointer first as this full() method + // is not a virtual method in parent class + stall_cond = ICNT_RC_FAIL; + } else if (!m_memory_config->SST_mode && + (m_icnt->full(size, inst.is_store() || inst.isatomic()))) { stall_cond = ICNT_RC_FAIL; } else { mem_fetch *mf = @@ -2282,7 +2423,7 @@ void sp_unit::active_lanes_in_pipeline() { void dp_unit::active_lanes_in_pipeline() { unsigned active_count = pipelined_simd_unit::get_active_lanes_in_pipeline(); assert(active_count <= m_core->get_config()->warp_size); - //m_core->incspactivelanes_stat(active_count); + // m_core->incspactivelanes_stat(active_count); m_core->incfuactivelanes_stat(active_count); m_core->incfumemactivelanes_stat(active_count); } @@ -2326,7 +2467,7 @@ sp_unit::sp_unit(register_set *result_port, const shader_core_config *config, specialized_unit::specialized_unit(register_set *result_port, const shader_core_config *config, - shader_core_ctx *core, unsigned supported_op, + shader_core_ctx *core, int supported_op, char *unit_name, unsigned latency, unsigned issue_reg_id) : pipelined_simd_unit(result_port, config, latency, core, issue_reg_id) { @@ -2414,8 +2555,10 @@ void pipelined_simd_unit::cycle() { if (!m_dispatch_reg->dispatch_delay()) { int start_stage = m_dispatch_reg->latency - m_dispatch_reg->initiation_interval; - move_warp(m_pipeline_reg[start_stage], m_dispatch_reg); - active_insts_in_pipeline++; + if (m_pipeline_reg[start_stage]->empty()) { + move_warp(m_pipeline_reg[start_stage], m_dispatch_reg); + active_insts_in_pipeline++; + } } } occupied >>= 1; @@ -2466,7 +2609,7 @@ void ldst_unit::init(mem_fetch_interface *icnt, IN_SHADER_L1T_ROB); m_L1C = new read_only_cache(L1C_name, m_config->m_L1C_config, m_sid, get_shader_constant_cache_id(), icnt, - IN_L1C_MISS_QUEUE); + IN_L1C_MISS_QUEUE, OTHER_GPU_CACHE, m_gpu); m_L1D = NULL; m_mem_rc = NO_RC_FAIL; m_num_writeback_clients = @@ -2482,9 +2625,10 @@ ldst_unit::ldst_unit(mem_fetch_interface *icnt, shader_core_ctx *core, opndcoll_rfu_t *operand_collector, Scoreboard *scoreboard, const shader_core_config *config, const memory_config *mem_config, shader_core_stats *stats, - unsigned sid, unsigned tpc) + unsigned sid, unsigned tpc, gpgpu_sim *gpu) : pipelined_simd_unit(NULL, config, config->smem_latency, core, 0), - m_next_wb(config) { + m_next_wb(config), + m_gpu(gpu) { assert(config->smem_latency > 1); init(icnt, mf_allocator, core, operand_collector, scoreboard, config, mem_config, stats, sid, tpc); @@ -2493,7 +2637,7 @@ ldst_unit::ldst_unit(mem_fetch_interface *icnt, snprintf(L1D_name, STRSIZE, "L1D_%03d", m_sid); m_L1D = new l1_cache(L1D_name, m_config->m_L1D_config, m_sid, get_shader_normal_cache_id(), m_icnt, m_mf_allocator, - IN_L1D_MISS_QUEUE, core->get_gpu()); + IN_L1D_MISS_QUEUE, core->get_gpu(), L1_GPU_CACHE); l1_latency_queue.resize(m_config->m_L1D_config.l1_banks); assert(m_config->m_L1D_config.l1_latency > 0); @@ -2533,6 +2677,9 @@ void ldst_unit::issue(register_set ®_set) { m_pending_writes[warp_id][reg_id] += n_accesses; } } + if (inst->m_is_ldgsts) { + m_pending_ldgsts[warp_id][inst->pc][inst->get_addr(0)] += n_accesses; + } } inst->op_pipe = MEM__OP; @@ -2564,11 +2711,24 @@ void ldst_unit::writeback() { m_next_wb.out[r]); insn_completed = true; } + } else if (m_next_wb.m_is_ldgsts) { // for LDGSTS instructions where no + // output register is used + m_pending_ldgsts[m_next_wb.warp_id()][m_next_wb.pc] + [m_next_wb.get_addr(0)]--; + if (m_pending_ldgsts[m_next_wb.warp_id()][m_next_wb.pc] + [m_next_wb.get_addr(0)] == 0) { + insn_completed = true; + } + break; } } if (insn_completed) { m_core->warp_inst_complete(m_next_wb); + if (m_next_wb.m_is_ldgsts) { + m_core->unset_depbar(m_next_wb); + } } + m_next_wb.clear(); m_last_inst_gpu_sim_cycle = m_core->get_gpu()->gpu_sim_cycle; m_last_inst_gpu_tot_sim_cycle = m_core->get_gpu()->gpu_tot_sim_cycle; @@ -2697,7 +2857,10 @@ void ldst_unit::cycle() { } } else { if (mf->get_type() == WRITE_ACK || - (m_config->gpgpu_perfect_mem && mf->get_is_write())) { + ((m_config->gpgpu_perfect_mem || m_memory_config->SST_mode) && + mf->get_is_write())) { + // SST memory is handled by SST mem hierarchy + // Perfect mem m_core->store_ack(mf); m_response_fifo.pop_front(); delete mf; @@ -2790,6 +2953,15 @@ void ldst_unit::cycle() { if (!pending_requests) { m_core->warp_inst_complete(*m_dispatch_reg); m_scoreboard->releaseRegisters(m_dispatch_reg); + + // release LDGSTS + if (m_dispatch_reg->m_is_ldgsts) { + // m_pending_ldgsts[m_dispatch_reg->warp_id()][m_dispatch_reg->pc][m_dispatch_reg->get_addr(0)]--; + if (m_pending_ldgsts[m_dispatch_reg->warp_id()][m_dispatch_reg->pc] + [m_dispatch_reg->get_addr(0)] == 0) { + m_core->unset_depbar(*m_dispatch_reg); + } + } } m_core->dec_inst_in_pipeline(warp_id); m_dispatch_reg->clear(); @@ -3078,7 +3250,7 @@ void warp_inst_t::print(FILE *fout) const { fprintf(fout, "bubble\n"); return; } else - fprintf(fout, "0x%04x ", pc); + fprintf(fout, "0x%04llx ", pc); fprintf(fout, "w%02d[", m_warp_id); for (unsigned j = 0; j < m_config->warp_size; j++) fprintf(fout, "%c", (active(j) ? '1' : '0')); @@ -3086,68 +3258,68 @@ void warp_inst_t::print(FILE *fout) const { m_config->gpgpu_ctx->func_sim->ptx_print_insn(pc, fout); fprintf(fout, "\n"); } -void shader_core_ctx::incexecstat(warp_inst_t *&inst) -{ - // Latency numbers for next operations are used to scale the power values - // for special operations, according observations from microbenchmarking - // TODO: put these numbers in the xml configuration - if(get_gpu()->get_config().g_power_simulation_enabled){ - switch(inst->sp_op){ - case INT__OP: - incialu_stat(inst->active_count(), scaling_coeffs->int_coeff); - break; - case INT_MUL_OP: - incimul_stat(inst->active_count(), scaling_coeffs->int_mul_coeff); - break; - case INT_MUL24_OP: - incimul24_stat(inst->active_count(), scaling_coeffs->int_mul24_coeff); - break; - case INT_MUL32_OP: - incimul32_stat(inst->active_count(), scaling_coeffs->int_mul32_coeff); - break; - case INT_DIV_OP: - incidiv_stat(inst->active_count(), scaling_coeffs->int_div_coeff); - break; - case FP__OP: - incfpalu_stat(inst->active_count(),scaling_coeffs->fp_coeff); - break; - case FP_MUL_OP: - incfpmul_stat(inst->active_count(), scaling_coeffs->fp_mul_coeff); - break; - case FP_DIV_OP: - incfpdiv_stat(inst->active_count(), scaling_coeffs->fp_div_coeff); - break; - case DP___OP: - incdpalu_stat(inst->active_count(), scaling_coeffs->dp_coeff); - break; - case DP_MUL_OP: - incdpmul_stat(inst->active_count(), scaling_coeffs->dp_mul_coeff); - break; - case DP_DIV_OP: - incdpdiv_stat(inst->active_count(), scaling_coeffs->dp_div_coeff); - break; - case FP_SQRT_OP: - incsqrt_stat(inst->active_count(), scaling_coeffs->sqrt_coeff); - break; - case FP_LG_OP: - inclog_stat(inst->active_count(), scaling_coeffs->log_coeff); - break; - case FP_SIN_OP: - incsin_stat(inst->active_count(), scaling_coeffs->sin_coeff); - break; - case FP_EXP_OP: - incexp_stat(inst->active_count(), scaling_coeffs->exp_coeff); - break; - case TENSOR__OP: - inctensor_stat(inst->active_count(), scaling_coeffs->tensor_coeff); - break; - case TEX__OP: - inctex_stat(inst->active_count(), scaling_coeffs->tex_coeff); - break; - default: - break; +void shader_core_ctx::incexecstat(warp_inst_t *&inst) { + // Latency numbers for next operations are used to scale the power values + // for special operations, according observations from microbenchmarking + // TODO: put these numbers in the xml configuration + if (get_gpu()->get_config().g_power_simulation_enabled) { + switch (inst->sp_op) { + case INT__OP: + incialu_stat(inst->active_count(), scaling_coeffs->int_coeff); + break; + case INT_MUL_OP: + incimul_stat(inst->active_count(), scaling_coeffs->int_mul_coeff); + break; + case INT_MUL24_OP: + incimul24_stat(inst->active_count(), scaling_coeffs->int_mul24_coeff); + break; + case INT_MUL32_OP: + incimul32_stat(inst->active_count(), scaling_coeffs->int_mul32_coeff); + break; + case INT_DIV_OP: + incidiv_stat(inst->active_count(), scaling_coeffs->int_div_coeff); + break; + case FP__OP: + incfpalu_stat(inst->active_count(), scaling_coeffs->fp_coeff); + break; + case FP_MUL_OP: + incfpmul_stat(inst->active_count(), scaling_coeffs->fp_mul_coeff); + break; + case FP_DIV_OP: + incfpdiv_stat(inst->active_count(), scaling_coeffs->fp_div_coeff); + break; + case DP___OP: + incdpalu_stat(inst->active_count(), scaling_coeffs->dp_coeff); + break; + case DP_MUL_OP: + incdpmul_stat(inst->active_count(), scaling_coeffs->dp_mul_coeff); + break; + case DP_DIV_OP: + incdpdiv_stat(inst->active_count(), scaling_coeffs->dp_div_coeff); + break; + case FP_SQRT_OP: + incsqrt_stat(inst->active_count(), scaling_coeffs->sqrt_coeff); + break; + case FP_LG_OP: + inclog_stat(inst->active_count(), scaling_coeffs->log_coeff); + break; + case FP_SIN_OP: + incsin_stat(inst->active_count(), scaling_coeffs->sin_coeff); + break; + case FP_EXP_OP: + incexp_stat(inst->active_count(), scaling_coeffs->exp_coeff); + break; + case TENSOR__OP: + inctensor_stat(inst->active_count(), scaling_coeffs->tensor_coeff); + break; + case TEX__OP: + inctex_stat(inst->active_count(), scaling_coeffs->tex_coeff); + break; + default: + break; } - if(inst->const_cache_operand) //warp has const address space load as one operand + if (inst->const_cache_operand) // warp has const address space load as one + // operand inc_const_accesses(1); } } @@ -3264,7 +3436,7 @@ void shader_core_ctx::display_pipeline(FILE *fout, int print_mem, if (!m_inst_fetch_buffer.m_valid) fprintf(fout, "bubble\n"); else { - fprintf(fout, "w%2u : pc = 0x%x, nbytes = %u\n", + fprintf(fout, "w%2u : pc = 0x%llx, nbytes = %u\n", m_inst_fetch_buffer.m_warp_id, m_inst_fetch_buffer.m_pc, m_inst_fetch_buffer.m_nbytes); } @@ -3497,7 +3669,7 @@ void shader_core_ctx::cycle() { execute(); read_operands(); issue(); - for (int i = 0; i < m_config->inst_fetch_throughput; ++i) { + for (unsigned int i = 0; i < m_config->inst_fetch_throughput; ++i) { decode(); fetch(); } @@ -3862,7 +4034,8 @@ void shader_core_ctx::accept_ldst_unit_response(mem_fetch *mf) { void shader_core_ctx::store_ack(class mem_fetch *mf) { assert(mf->get_type() == WRITE_ACK || - (m_config->gpgpu_perfect_mem && mf->get_is_write())); + ((m_config->gpgpu_perfect_mem || m_memory_config->SST_mode) && + mf->get_is_write())); unsigned warp_id = mf->get_wid(); m_warp[warp_id]->dec_store_req(); } @@ -3897,6 +4070,10 @@ void shader_core_ctx::get_icnt_power_stats(long &n_simt_to_mem, n_mem_to_simt += m_stats->n_mem_to_simt[m_sid]; } +kernel_info_t *shd_warp_t::get_kernel_info() const { + return m_shader->get_kernel_info(); +} + bool shd_warp_t::functional_done() const { return get_n_completed() == m_warp_size; } @@ -3922,13 +4099,16 @@ bool shd_warp_t::waiting() { // the functional execution of the atomic when it hits DRAM can cause // the wrong register to be read. return true; + } else if (m_waiting_ldgsts) { // Waiting for LDGSTS to finish + return true; } return false; } void shd_warp_t::print(FILE *fout) const { if (!done_exit()) { - fprintf(fout, "w%02u npc: 0x%04x, done:%c%c%c%c:%2u i:%u s:%u a:%u (done: ", + fprintf(fout, + "w%02u npc: 0x%04llx, done:%c%c%c%c:%2u i:%u s:%u a:%u (done: ", m_warp_id, m_next_pc, (functional_done() ? 'f' : ' '), (stores_done() ? 's' : ' '), (inst_in_pipeline() ? ' ' : 'i'), (done_exit() ? 'e' : ' '), n_completed, m_inst_in_pipeline, @@ -3997,14 +4177,11 @@ void opndcoll_rfu_t::init(unsigned num_banks, shader_core_ctx *shader) { // for( unsigned n=0; n<m_num_ports;n++ ) // m_dispatch_units[m_output[n]].init( m_num_collector_units[n] ); m_num_banks = num_banks; - m_bank_warp_shift = 0; m_warp_size = shader->get_config()->warp_size; - m_bank_warp_shift = (unsigned)(int)(log(m_warp_size + 0.5) / log(2.0)); - assert((m_bank_warp_shift == 5) || (m_warp_size != 32)); sub_core_model = shader->get_config()->sub_core_model; m_num_warp_scheds = shader->get_config()->gpgpu_num_sched_per_core; - unsigned reg_id; + unsigned reg_id = 0; if (sub_core_model) { assert(num_banks % shader->get_config()->gpgpu_num_sched_per_core == 0); assert(m_num_warp_scheds <= m_cu.size() && @@ -4018,20 +4195,20 @@ void opndcoll_rfu_t::init(unsigned num_banks, shader_core_ctx *shader) { unsigned cusPerSched = m_cu.size() / m_num_warp_scheds; reg_id = j / cusPerSched; } - m_cu[j]->init(j, num_banks, m_bank_warp_shift, shader->get_config(), this, - sub_core_model, reg_id, m_num_banks_per_sched); + m_cu[j]->init(j, num_banks, shader->get_config(), this, sub_core_model, + reg_id, m_num_banks_per_sched); } for (unsigned j = 0; j < m_dispatch_units.size(); j++) { - m_dispatch_units[j].init(sub_core_model,m_num_warp_scheds); + m_dispatch_units[j].init(sub_core_model, m_num_warp_scheds); } m_initialized = true; } -int register_bank(int regnum, int wid, unsigned num_banks, - unsigned bank_warp_shift, bool sub_core_model, - unsigned banks_per_sched, unsigned sched_id) { +unsigned register_bank(int regnum, int wid, unsigned num_banks, + bool sub_core_model, unsigned banks_per_sched, + unsigned sched_id) { int bank = regnum; - if (bank_warp_shift) bank += wid; + bank += wid; if (sub_core_model) { unsigned bank_num = (bank % banks_per_sched) + (sched_id * banks_per_sched); assert(bank_num < num_banks); @@ -4042,19 +4219,19 @@ int register_bank(int regnum, int wid, unsigned num_banks, bool opndcoll_rfu_t::writeback(warp_inst_t &inst) { assert(!inst.empty()); + std::list<unsigned> regs = m_shader->get_regs_written(inst); for (unsigned op = 0; op < MAX_REG_OPERANDS; op++) { int reg_num = inst.arch_reg.dst[op]; // this math needs to match that used // in function_info::ptx_decode_inst if (reg_num >= 0) { // valid register - unsigned bank = register_bank(reg_num, inst.warp_id(), m_num_banks, - m_bank_warp_shift, sub_core_model, - m_num_banks_per_sched, inst.get_schd_id()); + unsigned bank = + register_bank(reg_num, inst.warp_id(), m_num_banks, sub_core_model, + m_num_banks_per_sched, inst.get_schd_id()); if (m_arbiter.bank_idle(bank)) { m_arbiter.allocate_bank_for_write( - bank, - op_t(&inst, reg_num, m_num_banks, m_bank_warp_shift, sub_core_model, - m_num_banks_per_sched, inst.get_schd_id())); + bank, op_t(&inst, reg_num, m_num_banks, sub_core_model, + m_num_banks_per_sched, inst.get_schd_id())); inst.arch_reg.dst[op] = -1; } else { return false; @@ -4162,9 +4339,8 @@ void opndcoll_rfu_t::allocate_reads() { const op_t &rr = *r; unsigned reg = rr.get_reg(); unsigned wid = rr.get_wid(); - unsigned bank = - register_bank(reg, wid, m_num_banks, m_bank_warp_shift, sub_core_model, - m_num_banks_per_sched, rr.get_sid()); + unsigned bank = register_bank(reg, wid, m_num_banks, sub_core_model, + m_num_banks_per_sched, rr.get_sid()); m_arbiter.allocate_for_read(bank, rr); read_ops[bank] = rr; } @@ -4214,16 +4390,17 @@ void opndcoll_rfu_t::collector_unit_t::dump( } } -void opndcoll_rfu_t::collector_unit_t::init( - unsigned n, unsigned num_banks, unsigned log2_warp_size, - const core_config *config, opndcoll_rfu_t *rfu, bool sub_core_model, - unsigned reg_id, unsigned banks_per_sched) { +void opndcoll_rfu_t::collector_unit_t::init(unsigned n, unsigned num_banks, + const core_config *config, + opndcoll_rfu_t *rfu, + bool sub_core_model, + unsigned reg_id, + unsigned banks_per_sched) { m_rfu = rfu; m_cuid = n; m_num_banks = num_banks; assert(m_warp == NULL); m_warp = new warp_inst_t(config); - m_bank_warp_shift = log2_warp_size; m_sub_core_model = sub_core_model; m_reg_id = reg_id; m_num_banks_per_sched = banks_per_sched; @@ -4238,15 +4415,21 @@ bool opndcoll_rfu_t::collector_unit_t::allocate(register_set *pipeline_reg_set, warp_inst_t **pipeline_reg = pipeline_reg_set->get_ready(); if ((pipeline_reg) and !((*pipeline_reg)->empty())) { m_warp_id = (*pipeline_reg)->warp_id(); + std::vector<int> prev_regs; // remove duplicate regs within same instr for (unsigned op = 0; op < MAX_REG_OPERANDS; op++) { int reg_num = (*pipeline_reg) ->arch_reg.src[op]; // this math needs to match that used in // function_info::ptx_decode_inst - if (reg_num >= 0) { // valid register - m_src_op[op] = op_t(this, op, reg_num, m_num_banks, m_bank_warp_shift, - m_sub_core_model, m_num_banks_per_sched, - (*pipeline_reg)->get_schd_id()); + bool new_reg = true; + for (auto r : prev_regs) { + if (r == reg_num) new_reg = false; + } + if (reg_num >= 0 && new_reg) { // valid register + prev_regs.push_back(reg_num); + m_src_op[op] = + op_t(this, op, reg_num, m_num_banks, m_sub_core_model, + m_num_banks_per_sched, (*pipeline_reg)->get_schd_id()); m_not_ready.set(op); } else m_src_op[op] = op_t(); @@ -4405,7 +4588,46 @@ bool simt_core_cluster::icnt_injection_buffer_full(unsigned size, bool write) { return !::icnt_has_buffer(m_cluster_id, request_size); } +bool sst_simt_core_cluster::SST_injection_buffer_full(unsigned size, bool write, + mem_access_type type) { + switch (type) { + case CONST_ACC_R: + case INST_ACC_R: { + return response_queue_full(); + break; + } + default: { + return ::is_SST_buffer_full(m_cluster_id); + break; + } + } +} + void simt_core_cluster::icnt_inject_request_packet(class mem_fetch *mf) { + // Update stats based on mf type + update_icnt_stats(mf); + + // The packet size varies depending on the type of request: + // - For write request and atomic request, the packet contains the data + // - For read request (i.e. not write nor atomic), the packet only has control + // metadata + unsigned int packet_size = mf->size(); + if (!mf->get_is_write() && !mf->isatomic()) { + packet_size = mf->get_ctrl_size(); + } + m_stats->m_outgoing_traffic_stats->record_traffic(mf, packet_size); + unsigned destination = mf->get_sub_partition_id(); + mf->set_status(IN_ICNT_TO_MEM, + m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle); + if (!mf->get_is_write() && !mf->isatomic()) + ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void *)mf, + mf->get_ctrl_size()); + else + ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void *)mf, + mf->size()); +} + +void simt_core_cluster::update_icnt_stats(class mem_fetch *mf) { // stats if (mf->get_is_write()) m_stats->made_write_mfs++; @@ -4450,6 +4672,12 @@ void simt_core_cluster::icnt_inject_request_packet(class mem_fetch *mf) { default: assert(0); } +} + +void sst_simt_core_cluster::icnt_inject_request_packet_to_SST( + class mem_fetch *mf) { + // Update stats + update_icnt_stats(mf); // The packet size varies depending on the type of request: // - For write request and atomic request, the packet contains the data @@ -4460,15 +4688,25 @@ void simt_core_cluster::icnt_inject_request_packet(class mem_fetch *mf) { packet_size = mf->get_ctrl_size(); } m_stats->m_outgoing_traffic_stats->record_traffic(mf, packet_size); - unsigned destination = mf->get_sub_partition_id(); mf->set_status(IN_ICNT_TO_MEM, m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle); - if (!mf->get_is_write() && !mf->isatomic()) - ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void *)mf, - mf->get_ctrl_size()); - else - ::icnt_push(m_cluster_id, m_config->mem2device(destination), (void *)mf, - mf->size()); + switch (mf->get_access_type()) { + case CONST_ACC_R: + case INST_ACC_R: { + push_response_fifo(mf); + break; + } + default: { + if (!mf->get_is_write() && !mf->isatomic()) + ::send_read_request_SST(m_cluster_id, mf->get_addr(), + mf->get_data_size(), (void *)mf); + else + ::send_write_request_SST(m_cluster_id, mf->get_addr(), + mf->get_data_size(), (void *)mf); + + break; + } + } } void simt_core_cluster::icnt_cycle() { @@ -4510,6 +4748,49 @@ void simt_core_cluster::icnt_cycle() { } } +void sst_simt_core_cluster::icnt_cycle_SST() { + if (!m_response_fifo.empty()) { + mem_fetch *mf = m_response_fifo.front(); + unsigned cid = m_config->sid_to_cid(mf->get_sid()); + if (mf->get_access_type() == INST_ACC_R) { + // instruction fetch response + if (!m_core[cid]->fetch_unit_response_buffer_full()) { + m_response_fifo.pop_front(); + m_core[cid]->accept_fetch_response(mf); + } + } else { + // data response + if (!m_core[cid]->ldst_unit_response_buffer_full()) { + m_response_fifo.pop_front(); + m_memory_stats->memlatstat_read_done(mf); + m_core[cid]->accept_ldst_unit_response(mf); + } + } + } + + // pop from SST buffers + if (m_response_fifo.size() < m_config->n_simt_ejection_buffer_size) { + mem_fetch *mf = (mem_fetch *)(static_cast<sst_gpgpu_sim *>(get_gpu()) + ->SST_pop_mem_reply(m_cluster_id)); + if (!mf) return; + assert(mf->get_tpc() == m_cluster_id); + + // do atomic here + // For now, we execute atomic when the mem reply comes back + // This needs to be validated + if (mf && mf->isatomic()) mf->do_atomic(); + + unsigned int packet_size = + (mf->get_is_write()) ? mf->get_ctrl_size() : mf->size(); + m_stats->m_incoming_traffic_stats->record_traffic(mf, packet_size); + mf->set_status(IN_CLUSTER_TO_SHADER_QUEUE, + m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle); + // m_memory_stats->memlatstat_read_done(mf,m_shader_config->max_warps_per_shader); + m_response_fifo.push_back(mf); + m_stats->n_mem_to_simt[m_cluster_id] += mf->get_num_flits(false); + } +} + void simt_core_cluster::get_pdom_stack_top_info(unsigned sid, unsigned tid, unsigned *pc, unsigned *rpc) const { diff --git a/src/gpgpu-sim/shader.h b/src/gpgpu-sim/shader.h index 65d5625..ee10af6 100644 --- a/src/gpgpu-sim/shader.h +++ b/src/gpgpu-sim/shader.h @@ -1,17 +1,19 @@ // Copyright (c) 2009-2021, Tor M. Aamodt, Wilson W.L. Fung, Andrew Turner, -// Ali Bakhoda, Vijay Kandiah, Nikos Hardavellas -// The University of British Columbia, Northwestern University -// All rights reserved. +// Ali Bakhoda, Vijay Kandiah, Nikos Hardavellas, +// Mahmoud Khairy, Junrui Pan, Timothy G. Rogers +// The University of British Columbia, Northwestern University, Purdue +// University All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // -// 1. Redistributions of source code must retain the above copyright notice, this +// 1. Redistributions of source code must retain the above copyright notice, +// this // list of conditions and the following disclaimer; // 2. Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution; -// 3. Neither the names of The University of British Columbia, Northwestern +// 3. Neither the names of The University of British Columbia, Northwestern // University nor the names of their contributors may be used to // endorse or promote products derived from this software without specific // prior written permission. @@ -118,14 +120,30 @@ class shd_warp_t { m_done_exit = true; m_last_fetch = 0; m_next = 0; + m_streamID = (unsigned long long)-1; // Jin: cdp support m_cdp_latency = 0; m_cdp_dummy = false; + + // Ni: Initialize ldgdepbar_id + m_ldgdepbar_id = 0; + m_depbar_start_id = 0; + m_depbar_group = 0; + + // Ni: Set waiting to false + m_waiting_ldgsts = false; + + // Ni: Clear m_ldgdepbar_buf + for (unsigned i = 0; i < m_ldgdepbar_buf.size(); i++) { + m_ldgdepbar_buf[i].clear(); + } + m_ldgdepbar_buf.clear(); } void init(address_type start_pc, unsigned cta_id, unsigned wid, - const std::bitset<MAX_WARP_SIZE> &active, - unsigned dynamic_warp_id) { + const std::bitset<MAX_WARP_SIZE> &active, unsigned dynamic_warp_id, + unsigned long long streamID) { + m_streamID = streamID; m_cta_id = cta_id; m_warp_id = wid; m_dynamic_warp_id = dynamic_warp_id; @@ -139,6 +157,20 @@ class shd_warp_t { // Jin: cdp support m_cdp_latency = 0; m_cdp_dummy = false; + + // Ni: Initialize ldgdepbar_id + m_ldgdepbar_id = 0; + m_depbar_start_id = 0; + m_depbar_group = 0; + + // Ni: Set waiting to false + m_waiting_ldgsts = false; + + // Ni: Clear m_ldgdepbar_buf + for (unsigned i = 0; i < m_ldgdepbar_buf.size(); i++) { + m_ldgdepbar_buf[i].clear(); + } + m_ldgdepbar_buf.clear(); } bool functional_done() const; @@ -170,6 +202,7 @@ class shd_warp_t { void clear_membar() { m_membar = false; } bool get_membar() const { return m_membar; } virtual address_type get_pc() const { return m_next_pc; } + virtual kernel_info_t *get_kernel_info() const; void set_next_pc(address_type pc) { m_next_pc = pc; } void store_info_of_last_inst_at_barrier(const warp_inst_t *pI) { @@ -234,6 +267,7 @@ class shd_warp_t { m_inst_in_pipeline--; } + unsigned long long get_streamID() const { return m_streamID; } unsigned get_cta_id() const { return m_cta_id; } unsigned get_dynamic_warp_id() const { return m_dynamic_warp_id; } @@ -246,6 +280,7 @@ class shd_warp_t { private: static const unsigned IBUFFER_SIZE = 2; class shader_core_ctx *m_shader; + unsigned long long m_streamID; unsigned m_cta_id; unsigned m_warp_id; unsigned m_warp_size; @@ -286,6 +321,16 @@ class shd_warp_t { public: unsigned int m_cdp_latency; bool m_cdp_dummy; + + // Ni: LDGDEPBAR barrier support + public: + unsigned int m_ldgdepbar_id; // LDGDEPBAR barrier ID + std::vector<std::vector<warp_inst_t>> + m_ldgdepbar_buf; // LDGDEPBAR barrier buffer + unsigned int m_depbar_start_id; + unsigned int m_depbar_group; + bool m_waiting_ldgsts; // Ni: Whether the warp is waiting for the LDGSTS + // instrs to finish }; inline unsigned hw_tid_from_wid(unsigned wid, unsigned warp_size, unsigned i) { @@ -298,9 +343,9 @@ inline unsigned wid_from_hw_tid(unsigned tid, unsigned warp_size) { const unsigned WARP_PER_CTA_MAX = 64; typedef std::bitset<WARP_PER_CTA_MAX> warp_set_t; -int register_bank(int regnum, int wid, unsigned num_banks, - unsigned bank_warp_shift, bool sub_core_model, - unsigned banks_per_sched, unsigned sched_id); +unsigned register_bank(int regnum, int wid, unsigned num_banks, + bool sub_core_model, unsigned banks_per_sched, + unsigned sched_id); class shader_core_ctx; class shader_core_config; @@ -349,8 +394,8 @@ class scheduler_unit { // this can be copied freely, so can be used in std m_sfu_out(sfu_out), m_int_out(int_out), m_tensor_core_out(tensor_core_out), - m_spec_cores_out(spec_cores_out), m_mem_out(mem_out), + m_spec_cores_out(spec_cores_out), m_id(id) {} virtual ~scheduler_unit() {} virtual void add_supervised_warp_id(int i) { @@ -643,28 +688,26 @@ class opndcoll_rfu_t { // operand collector based register file unit public: op_t() { m_valid = false; } op_t(collector_unit_t *cu, unsigned op, unsigned reg, unsigned num_banks, - unsigned bank_warp_shift, bool sub_core_model, - unsigned banks_per_sched, unsigned sched_id) { + bool sub_core_model, unsigned banks_per_sched, unsigned sched_id) { m_valid = true; m_warp = NULL; m_cu = cu; m_operand = op; m_register = reg; m_shced_id = sched_id; - m_bank = register_bank(reg, cu->get_warp_id(), num_banks, bank_warp_shift, - sub_core_model, banks_per_sched, sched_id); + m_bank = register_bank(reg, cu->get_warp_id(), num_banks, sub_core_model, + banks_per_sched, sched_id); } op_t(const warp_inst_t *warp, unsigned reg, unsigned num_banks, - unsigned bank_warp_shift, bool sub_core_model, - unsigned banks_per_sched, unsigned sched_id) { + bool sub_core_model, unsigned banks_per_sched, unsigned sched_id) { m_valid = true; m_warp = warp; m_register = reg; m_cu = NULL; m_operand = -1; m_shced_id = sched_id; - m_bank = register_bank(reg, warp->warp_id(), num_banks, bank_warp_shift, - sub_core_model, banks_per_sched, sched_id); + m_bank = register_bank(reg, warp->warp_id(), num_banks, sub_core_model, + banks_per_sched, sched_id); } // accessors @@ -896,7 +939,6 @@ class opndcoll_rfu_t { // operand collector based register file unit m_not_ready.reset(); m_warp_id = -1; m_num_banks = 0; - m_bank_warp_shift = 0; } // accessors bool ready() const; @@ -913,9 +955,8 @@ class opndcoll_rfu_t { // operand collector based register file unit unsigned get_reg_id() const { return m_reg_id; } // modifiers - void init(unsigned n, unsigned num_banks, unsigned log2_warp_size, - const core_config *config, opndcoll_rfu_t *rfu, - bool m_sub_core_model, unsigned reg_id, + void init(unsigned n, unsigned num_banks, const core_config *config, + opndcoll_rfu_t *rfu, bool m_sub_core_model, unsigned reg_id, unsigned num_banks_per_sched); bool allocate(register_set *pipeline_reg, register_set *output_reg); @@ -935,7 +976,6 @@ class opndcoll_rfu_t { // operand collector based register file unit op_t *m_src_op; std::bitset<MAX_REG_OPERANDS * 2> m_not_ready; unsigned m_num_banks; - unsigned m_bank_warp_shift; opndcoll_rfu_t *m_rfu; unsigned m_num_banks_per_sched; @@ -954,41 +994,19 @@ class opndcoll_rfu_t { // operand collector based register file unit void init(bool sub_core_model, unsigned num_warp_scheds) { m_sub_core_model = sub_core_model; m_num_warp_scheds = num_warp_scheds; - if (m_sub_core_model) { - m_last_cu_set = new unsigned(m_num_warp_scheds); - for (unsigned i = 0; i < m_num_warp_scheds; i++) - { - m_last_cu_set[i] = i * m_num_collectors / m_num_warp_scheds; - } - } - } collector_unit_t *find_ready() { - if (m_sub_core_model) { - assert(m_num_collectors % m_num_warp_scheds == 0 && - m_num_collectors >= m_num_warp_scheds); - unsigned cusPerSched = m_num_collectors / m_num_warp_scheds; - for (unsigned i = 0; i < m_num_warp_scheds; i++) { - unsigned cuLowerBound = i * cusPerSched; - unsigned cuUpperBound = cuLowerBound + cusPerSched; - assert(0 <= cuLowerBound && cuUpperBound <= m_num_collectors); - assert(cuLowerBound <= m_last_cu_set[i] && m_last_cu_set[i] <= cuUpperBound); - for (unsigned j = cuLowerBound; j < cuUpperBound; j++) { - unsigned c = cuLowerBound + (m_last_cu_set[i] + j + 1) % cusPerSched; - if ((*m_collector_units)[c].ready()) { - m_last_cu_set[i] = c; - return &((*m_collector_units)[c]); - } - } - } - } else { - for (unsigned n = 0; n < m_num_collectors; n++) { - unsigned c = (m_last_cu + n + 1) % m_num_collectors; - if ((*m_collector_units)[c].ready()) { - m_last_cu = c; - return &((*m_collector_units)[c]); - } + // With sub-core enabled round robin starts with the next cu assigned to a + // different sub-core than the one that dispatched last + unsigned cusPerSched = m_num_collectors / m_num_warp_scheds; + unsigned rr_increment = + m_sub_core_model ? cusPerSched - (m_last_cu % cusPerSched) : 1; + for (unsigned n = 0; n < m_num_collectors; n++) { + unsigned c = (m_last_cu + n + rr_increment) % m_num_collectors; + if ((*m_collector_units)[c].ready()) { + m_last_cu = c; + return &((*m_collector_units)[c]); } } return NULL; @@ -998,9 +1016,7 @@ class opndcoll_rfu_t { // operand collector based register file unit unsigned m_num_collectors; std::vector<collector_unit_t> *m_collector_units; unsigned m_last_cu; // dispatch ready cu's rr - unsigned *m_last_cu_set; unsigned m_next_cu; // for initialization - bool m_sub_core_model; unsigned m_num_warp_scheds; }; @@ -1011,7 +1027,6 @@ class opndcoll_rfu_t { // operand collector based register file unit unsigned m_num_collector_sets; // unsigned m_num_collectors; unsigned m_num_banks; - unsigned m_bank_warp_shift; unsigned m_warp_size; std::vector<collector_unit_t *> m_cu; arbiter_t m_arbiter; @@ -1306,8 +1321,8 @@ class sp_unit : public pipelined_simd_unit { class specialized_unit : public pipelined_simd_unit { public: specialized_unit(register_set *result_port, const shader_core_config *config, - shader_core_ctx *core, unsigned supported_op, - char *unit_name, unsigned latency, unsigned issue_reg_id); + shader_core_ctx *core, int supported_op, char *unit_name, + unsigned latency, unsigned issue_reg_id); virtual bool can_issue(const warp_inst_t &inst) const { if (inst.op != m_supported_op) { return false; @@ -1319,7 +1334,7 @@ class specialized_unit : public pipelined_simd_unit { bool is_issue_partitioned() { return true; } private: - unsigned m_supported_op; + int m_supported_op; }; class simt_core_cluster; @@ -1334,8 +1349,18 @@ class ldst_unit : public pipelined_simd_unit { shader_core_ctx *core, opndcoll_rfu_t *operand_collector, Scoreboard *scoreboard, const shader_core_config *config, const memory_config *mem_config, class shader_core_stats *stats, - unsigned sid, unsigned tpc); + unsigned sid, unsigned tpc, gpgpu_sim *gpu); + // Add a structure to record the LDGSTS instructions, + // similar to m_pending_writes, but since LDGSTS does not have a output + // register to write to, so a new structure needs to be added + /* A multi-level map: unsigned (warp_id) -> unsigned (pc) -> unsigned (addr) + * -> unsigned (count) + */ + std::map<unsigned /*warp_id*/, + std::map<unsigned /*pc*/, + std::map<unsigned /*addr*/, unsigned /*count*/>>> + m_pending_ldgsts; // modifiers virtual void issue(register_set &inst); bool is_issue_partitioned() { return false; } @@ -1414,6 +1439,7 @@ class ldst_unit : public pipelined_simd_unit { warp_inst_t &inst); mem_stage_stall_type process_memory_access_queue_l1cache(l1_cache *cache, warp_inst_t &inst); + gpgpu_sim *m_gpu; const memory_config *m_memory_config; class mem_fetch_interface *m_icnt; @@ -1644,13 +1670,13 @@ class shader_core_config : public core_config { unsigned int gpgpu_operand_collector_num_out_ports_gen; unsigned int gpgpu_operand_collector_num_out_ports_int; - int gpgpu_num_sp_units; - int gpgpu_tensor_core_avail; - int gpgpu_num_dp_units; - int gpgpu_num_sfu_units; - int gpgpu_num_tensor_core_units; - int gpgpu_num_mem_units; - int gpgpu_num_int_units; + unsigned int gpgpu_num_sp_units; + unsigned int gpgpu_tensor_core_avail; + unsigned int gpgpu_num_dp_units; + unsigned int gpgpu_num_sfu_units; + unsigned int gpgpu_num_tensor_core_units; + unsigned int gpgpu_num_mem_units; + unsigned int gpgpu_num_int_units; // Shader core resources unsigned gpgpu_shader_registers; @@ -1746,8 +1772,8 @@ struct shader_core_stats_pod { unsigned *m_active_tensor_core_lanes; unsigned *m_active_fu_lanes; unsigned *m_active_fu_mem_lanes; - double *m_active_exu_threads; //For power model - double *m_active_exu_warps; //For power model + double *m_active_exu_threads; // For power model + double *m_active_exu_warps; // For power model unsigned *m_n_diverge; // number of divergence occurring in this shader unsigned gpgpu_n_load_insn; unsigned gpgpu_n_store_insn; @@ -1757,7 +1783,7 @@ struct shader_core_stats_pod { unsigned gpgpu_n_const_insn; unsigned gpgpu_n_param_insn; unsigned gpgpu_n_shmem_bkconflict; - unsigned gpgpu_n_cache_bkconflict; + unsigned gpgpu_n_l1cache_bkconflict; int gpgpu_n_intrawarp_mshr_merge; unsigned gpgpu_n_cmem_portconflict; unsigned gpu_stall_shd_mem_breakdown[N_MEM_STAGE_ACCESS_TYPE] @@ -1818,56 +1844,41 @@ class shader_core_stats : public shader_core_stats_pod { (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); m_num_loadqueued_insn = (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); - m_num_tex_inst = - (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); + m_num_tex_inst = (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); m_num_INTdecoded_insn = (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); - m_num_ialu_acesses = - (double *)calloc(config->num_shader(), sizeof(double)); - m_num_fp_acesses = - (double *)calloc(config->num_shader(), sizeof(double)); - m_num_imul_acesses = - (double *)calloc(config->num_shader(), sizeof(double)); + m_num_ialu_acesses = (double *)calloc(config->num_shader(), sizeof(double)); + m_num_fp_acesses = (double *)calloc(config->num_shader(), sizeof(double)); + m_num_imul_acesses = (double *)calloc(config->num_shader(), sizeof(double)); m_num_imul24_acesses = (double *)calloc(config->num_shader(), sizeof(double)); m_num_imul32_acesses = (double *)calloc(config->num_shader(), sizeof(double)); m_num_fpmul_acesses = (double *)calloc(config->num_shader(), sizeof(double)); - m_num_idiv_acesses = - (double *)calloc(config->num_shader(), sizeof(double)); + m_num_idiv_acesses = (double *)calloc(config->num_shader(), sizeof(double)); m_num_fpdiv_acesses = (double *)calloc(config->num_shader(), sizeof(double)); - m_num_dp_acesses = - (double*) calloc(config->num_shader(),sizeof(double)); - m_num_dpmul_acesses = - (double*) calloc(config->num_shader(),sizeof(double)); - m_num_dpdiv_acesses = - (double*) calloc(config->num_shader(),sizeof(double)); - m_num_sp_acesses = + m_num_dp_acesses = (double *)calloc(config->num_shader(), sizeof(double)); + m_num_dpmul_acesses = (double *)calloc(config->num_shader(), sizeof(double)); - m_num_sfu_acesses = + m_num_dpdiv_acesses = (double *)calloc(config->num_shader(), sizeof(double)); - m_num_tensor_core_acesses = + m_num_sp_acesses = (double *)calloc(config->num_shader(), sizeof(double)); + m_num_sfu_acesses = (double *)calloc(config->num_shader(), sizeof(double)); + m_num_tensor_core_acesses = (double *)calloc(config->num_shader(), sizeof(double)); m_num_const_acesses = (double *)calloc(config->num_shader(), sizeof(double)); - m_num_tex_acesses = - (double *)calloc(config->num_shader(), sizeof(double)); - m_num_sqrt_acesses = - (double*) calloc(config->num_shader(),sizeof(double)); - m_num_log_acesses = - (double*) calloc(config->num_shader(),sizeof(double)); - m_num_sin_acesses = - (double*) calloc(config->num_shader(),sizeof(double)); - m_num_exp_acesses = - (double*) calloc(config->num_shader(),sizeof(double)); - m_num_mem_acesses = - (double *)calloc(config->num_shader(), sizeof(double)); + m_num_tex_acesses = (double *)calloc(config->num_shader(), sizeof(double)); + m_num_sqrt_acesses = (double *)calloc(config->num_shader(), sizeof(double)); + m_num_log_acesses = (double *)calloc(config->num_shader(), sizeof(double)); + m_num_sin_acesses = (double *)calloc(config->num_shader(), sizeof(double)); + m_num_exp_acesses = (double *)calloc(config->num_shader(), sizeof(double)); + m_num_mem_acesses = (double *)calloc(config->num_shader(), sizeof(double)); m_num_sp_committed = (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); - m_num_tlb_hits = - (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); + m_num_tlb_hits = (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); m_num_tlb_accesses = (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); m_active_sp_lanes = @@ -1880,8 +1891,7 @@ class shader_core_stats : public shader_core_stats_pod { (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); m_active_exu_threads = (double *)calloc(config->num_shader(), sizeof(double)); - m_active_exu_warps = - (double *)calloc(config->num_shader(), sizeof(double)); + m_active_exu_warps = (double *)calloc(config->num_shader(), sizeof(double)); m_active_fu_mem_lanes = (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); m_num_sfu_committed = @@ -1896,8 +1906,7 @@ class shader_core_stats : public shader_core_stats_pod { (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); m_non_rf_operands = (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); - m_n_diverge = - (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); + m_n_diverge = (unsigned *)calloc(config->num_shader(), sizeof(unsigned)); shader_cycle_distro = (unsigned *)calloc(config->warp_size + 3, sizeof(unsigned)); last_shader_cycle_distro = @@ -2006,6 +2015,7 @@ class shader_core_stats : public shader_core_stats_pod { friend class shader_core_ctx; friend class ldst_unit; friend class simt_core_cluster; + friend class sst_simt_core_cluster; friend class scheduler_unit; friend class TwoLevelScheduler; friend class LooseRoundRobbinScheduler; @@ -2021,18 +2031,20 @@ class shader_core_mem_fetch_allocator : public mem_fetch_allocator { m_memory_config = config; } mem_fetch *alloc(new_addr_type addr, mem_access_type type, unsigned size, - bool wr, unsigned long long cycle) const; + bool wr, unsigned long long cycle, + unsigned long long streamID) const; mem_fetch *alloc(new_addr_type addr, mem_access_type type, const active_mask_t &active_mask, const mem_access_byte_mask_t &byte_mask, const mem_access_sector_mask_t §or_mask, unsigned size, bool wr, unsigned long long cycle, unsigned wid, - unsigned sid, unsigned tpc, mem_fetch *original_mf) const; + unsigned sid, unsigned tpc, mem_fetch *original_mf, + unsigned long long streamID) const; mem_fetch *alloc(const warp_inst_t &inst, const mem_access_t &access, unsigned long long cycle) const { warp_inst_t inst_copy = inst; mem_fetch *mf = new mem_fetch( - access, &inst_copy, + access, &inst_copy, inst.get_streamID(), access.is_write() ? WRITE_PACKET_SIZE : READ_PACKET_SIZE, inst.warp_id(), m_core_id, m_cluster_id, m_memory_config, cycle); return mf; @@ -2091,6 +2103,9 @@ class shader_core_ctx : public core_t { // modifiers virtual void warp_exit(unsigned warp_id); + // Ni: Unset ldgdepbar + void unset_depbar(const warp_inst_t &inst); + // accessors virtual bool warp_waiting_at_barrier(unsigned warp_id) const; void get_pdom_stack_top_info(unsigned tid, unsigned *pc, unsigned *rpc) const; @@ -2130,206 +2145,244 @@ class shader_core_ctx : public core_t { void incload_stat() { m_stats->m_num_loadqueued_insn[m_sid]++; } void incstore_stat() { m_stats->m_num_storequeued_insn[m_sid]++; } - void incialu_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_ialu_acesses[m_sid]=m_stats->m_num_ialu_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_nonsfu(active_count, latency); - }else { - m_stats->m_num_ialu_acesses[m_sid]=m_stats->m_num_ialu_acesses[m_sid]+(double)active_count*latency; + void incialu_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_ialu_acesses[m_sid] = + m_stats->m_num_ialu_acesses[m_sid] + (double)active_count * latency + + inactive_lanes_accesses_nonsfu(active_count, latency); + } else { + m_stats->m_num_ialu_acesses[m_sid] = + m_stats->m_num_ialu_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; + m_stats->m_active_exu_threads[m_sid] += active_count; m_stats->m_active_exu_warps[m_sid]++; } - void incimul_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_imul_acesses[m_sid]=m_stats->m_num_imul_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_nonsfu(active_count, latency); - }else { - m_stats->m_num_imul_acesses[m_sid]=m_stats->m_num_imul_acesses[m_sid]+(double)active_count*latency; + void incimul_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_imul_acesses[m_sid] = + m_stats->m_num_imul_acesses[m_sid] + (double)active_count * latency + + inactive_lanes_accesses_nonsfu(active_count, latency); + } else { + m_stats->m_num_imul_acesses[m_sid] = + m_stats->m_num_imul_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; + m_stats->m_active_exu_threads[m_sid] += active_count; m_stats->m_active_exu_warps[m_sid]++; } - void incimul24_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_imul24_acesses[m_sid]=m_stats->m_num_imul24_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_nonsfu(active_count, latency); - }else { - m_stats->m_num_imul24_acesses[m_sid]=m_stats->m_num_imul24_acesses[m_sid]+(double)active_count*latency; + void incimul24_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_imul24_acesses[m_sid] = + m_stats->m_num_imul24_acesses[m_sid] + + (double)active_count * latency + + inactive_lanes_accesses_nonsfu(active_count, latency); + } else { + m_stats->m_num_imul24_acesses[m_sid] = + m_stats->m_num_imul24_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; - m_stats->m_active_exu_warps[m_sid]++; - } - void incimul32_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_imul32_acesses[m_sid]=m_stats->m_num_imul32_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_sfu(active_count, latency); - }else{ - m_stats->m_num_imul32_acesses[m_sid]=m_stats->m_num_imul32_acesses[m_sid]+(double)active_count*latency; + m_stats->m_active_exu_threads[m_sid] += active_count; + m_stats->m_active_exu_warps[m_sid]++; + } + void incimul32_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_imul32_acesses[m_sid] = + m_stats->m_num_imul32_acesses[m_sid] + + (double)active_count * latency + + inactive_lanes_accesses_sfu(active_count, latency); + } else { + m_stats->m_num_imul32_acesses[m_sid] = + m_stats->m_num_imul32_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; + m_stats->m_active_exu_threads[m_sid] += active_count; m_stats->m_active_exu_warps[m_sid]++; } - void incidiv_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_idiv_acesses[m_sid]=m_stats->m_num_idiv_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_sfu(active_count, latency); - }else { - m_stats->m_num_idiv_acesses[m_sid]=m_stats->m_num_idiv_acesses[m_sid]+(double)active_count*latency; + void incidiv_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_idiv_acesses[m_sid] = + m_stats->m_num_idiv_acesses[m_sid] + (double)active_count * latency + + inactive_lanes_accesses_sfu(active_count, latency); + } else { + m_stats->m_num_idiv_acesses[m_sid] = + m_stats->m_num_idiv_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; - m_stats->m_active_exu_warps[m_sid]++; + m_stats->m_active_exu_threads[m_sid] += active_count; + m_stats->m_active_exu_warps[m_sid]++; } - void incfpalu_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_fp_acesses[m_sid]=m_stats->m_num_fp_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_nonsfu(active_count, latency); - }else { - m_stats->m_num_fp_acesses[m_sid]=m_stats->m_num_fp_acesses[m_sid]+(double)active_count*latency; + void incfpalu_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_fp_acesses[m_sid] = + m_stats->m_num_fp_acesses[m_sid] + (double)active_count * latency + + inactive_lanes_accesses_nonsfu(active_count, latency); + } else { + m_stats->m_num_fp_acesses[m_sid] = + m_stats->m_num_fp_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; - m_stats->m_active_exu_warps[m_sid]++; + m_stats->m_active_exu_threads[m_sid] += active_count; + m_stats->m_active_exu_warps[m_sid]++; } - void incfpmul_stat(unsigned active_count,double latency) { - // printf("FP MUL stat increament\n"); - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_fpmul_acesses[m_sid]=m_stats->m_num_fpmul_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_nonsfu(active_count, latency); - }else { - m_stats->m_num_fpmul_acesses[m_sid]=m_stats->m_num_fpmul_acesses[m_sid]+(double)active_count*latency; + void incfpmul_stat(unsigned active_count, double latency) { + // printf("FP MUL stat increament\n"); + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_fpmul_acesses[m_sid] = + m_stats->m_num_fpmul_acesses[m_sid] + (double)active_count * latency + + inactive_lanes_accesses_nonsfu(active_count, latency); + } else { + m_stats->m_num_fpmul_acesses[m_sid] = + m_stats->m_num_fpmul_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; + m_stats->m_active_exu_threads[m_sid] += active_count; m_stats->m_active_exu_warps[m_sid]++; - } - void incfpdiv_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_fpdiv_acesses[m_sid]=m_stats->m_num_fpdiv_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_sfu(active_count, latency); - }else { - m_stats->m_num_fpdiv_acesses[m_sid]=m_stats->m_num_fpdiv_acesses[m_sid]+(double)active_count*latency; + } + void incfpdiv_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_fpdiv_acesses[m_sid] = + m_stats->m_num_fpdiv_acesses[m_sid] + (double)active_count * latency + + inactive_lanes_accesses_sfu(active_count, latency); + } else { + m_stats->m_num_fpdiv_acesses[m_sid] = + m_stats->m_num_fpdiv_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; + m_stats->m_active_exu_threads[m_sid] += active_count; m_stats->m_active_exu_warps[m_sid]++; - } - void incdpalu_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_dp_acesses[m_sid]=m_stats->m_num_dp_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_nonsfu(active_count, latency); - }else { - m_stats->m_num_dp_acesses[m_sid]=m_stats->m_num_dp_acesses[m_sid]+(double)active_count*latency; + } + void incdpalu_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_dp_acesses[m_sid] = + m_stats->m_num_dp_acesses[m_sid] + (double)active_count * latency + + inactive_lanes_accesses_nonsfu(active_count, latency); + } else { + m_stats->m_num_dp_acesses[m_sid] = + m_stats->m_num_dp_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; - m_stats->m_active_exu_warps[m_sid]++; - } - void incdpmul_stat(unsigned active_count,double latency) { - // printf("FP MUL stat increament\n"); - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_dpmul_acesses[m_sid]=m_stats->m_num_dpmul_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_nonsfu(active_count, latency); - }else { - m_stats->m_num_dpmul_acesses[m_sid]=m_stats->m_num_dpmul_acesses[m_sid]+(double)active_count*latency; + m_stats->m_active_exu_threads[m_sid] += active_count; + m_stats->m_active_exu_warps[m_sid]++; + } + void incdpmul_stat(unsigned active_count, double latency) { + // printf("FP MUL stat increament\n"); + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_dpmul_acesses[m_sid] = + m_stats->m_num_dpmul_acesses[m_sid] + (double)active_count * latency + + inactive_lanes_accesses_nonsfu(active_count, latency); + } else { + m_stats->m_num_dpmul_acesses[m_sid] = + m_stats->m_num_dpmul_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; + m_stats->m_active_exu_threads[m_sid] += active_count; m_stats->m_active_exu_warps[m_sid]++; - } - void incdpdiv_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_dpdiv_acesses[m_sid]=m_stats->m_num_dpdiv_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_sfu(active_count, latency); - }else { - m_stats->m_num_dpdiv_acesses[m_sid]=m_stats->m_num_dpdiv_acesses[m_sid]+(double)active_count*latency; + } + void incdpdiv_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_dpdiv_acesses[m_sid] = + m_stats->m_num_dpdiv_acesses[m_sid] + (double)active_count * latency + + inactive_lanes_accesses_sfu(active_count, latency); + } else { + m_stats->m_num_dpdiv_acesses[m_sid] = + m_stats->m_num_dpdiv_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; + m_stats->m_active_exu_threads[m_sid] += active_count; m_stats->m_active_exu_warps[m_sid]++; - } + } - void incsqrt_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_sqrt_acesses[m_sid]=m_stats->m_num_sqrt_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_sfu(active_count, latency); - }else{ - m_stats->m_num_sqrt_acesses[m_sid]=m_stats->m_num_sqrt_acesses[m_sid]+(double)active_count*latency; + void incsqrt_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_sqrt_acesses[m_sid] = + m_stats->m_num_sqrt_acesses[m_sid] + (double)active_count * latency + + inactive_lanes_accesses_sfu(active_count, latency); + } else { + m_stats->m_num_sqrt_acesses[m_sid] = + m_stats->m_num_sqrt_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; + m_stats->m_active_exu_threads[m_sid] += active_count; m_stats->m_active_exu_warps[m_sid]++; - } + } - void inclog_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_log_acesses[m_sid]=m_stats->m_num_log_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_sfu(active_count, latency); - }else{ - m_stats->m_num_log_acesses[m_sid]=m_stats->m_num_log_acesses[m_sid]+(double)active_count*latency; + void inclog_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_log_acesses[m_sid] = + m_stats->m_num_log_acesses[m_sid] + (double)active_count * latency + + inactive_lanes_accesses_sfu(active_count, latency); + } else { + m_stats->m_num_log_acesses[m_sid] = + m_stats->m_num_log_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; + m_stats->m_active_exu_threads[m_sid] += active_count; m_stats->m_active_exu_warps[m_sid]++; - } + } - void incexp_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_exp_acesses[m_sid]=m_stats->m_num_exp_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_sfu(active_count, latency); - }else{ - m_stats->m_num_exp_acesses[m_sid]=m_stats->m_num_exp_acesses[m_sid]+(double)active_count*latency; + void incexp_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_exp_acesses[m_sid] = + m_stats->m_num_exp_acesses[m_sid] + (double)active_count * latency + + inactive_lanes_accesses_sfu(active_count, latency); + } else { + m_stats->m_num_exp_acesses[m_sid] = + m_stats->m_num_exp_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; + m_stats->m_active_exu_threads[m_sid] += active_count; m_stats->m_active_exu_warps[m_sid]++; } - void incsin_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_sin_acesses[m_sid]=m_stats->m_num_sin_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_sfu(active_count, latency); - }else{ - m_stats->m_num_sin_acesses[m_sid]=m_stats->m_num_sin_acesses[m_sid]+(double)active_count*latency; + void incsin_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_sin_acesses[m_sid] = + m_stats->m_num_sin_acesses[m_sid] + (double)active_count * latency + + inactive_lanes_accesses_sfu(active_count, latency); + } else { + m_stats->m_num_sin_acesses[m_sid] = + m_stats->m_num_sin_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; + m_stats->m_active_exu_threads[m_sid] += active_count; m_stats->m_active_exu_warps[m_sid]++; } - - void inctensor_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_tensor_core_acesses[m_sid]=m_stats->m_num_tensor_core_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_sfu(active_count, latency); - }else{ - m_stats->m_num_tensor_core_acesses[m_sid]=m_stats->m_num_tensor_core_acesses[m_sid]+(double)active_count*latency; + void inctensor_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_tensor_core_acesses[m_sid] = + m_stats->m_num_tensor_core_acesses[m_sid] + + (double)active_count * latency + + inactive_lanes_accesses_sfu(active_count, latency); + } else { + m_stats->m_num_tensor_core_acesses[m_sid] = + m_stats->m_num_tensor_core_acesses[m_sid] + + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; + m_stats->m_active_exu_threads[m_sid] += active_count; m_stats->m_active_exu_warps[m_sid]++; } - void inctex_stat(unsigned active_count,double latency) { - if(m_config->gpgpu_clock_gated_lanes==false){ - m_stats->m_num_tex_acesses[m_sid]=m_stats->m_num_tex_acesses[m_sid]+(double)active_count*latency - + inactive_lanes_accesses_sfu(active_count, latency); - }else{ - m_stats->m_num_tex_acesses[m_sid]=m_stats->m_num_tex_acesses[m_sid]+(double)active_count*latency; + void inctex_stat(unsigned active_count, double latency) { + if (m_config->gpgpu_clock_gated_lanes == false) { + m_stats->m_num_tex_acesses[m_sid] = + m_stats->m_num_tex_acesses[m_sid] + (double)active_count * latency + + inactive_lanes_accesses_sfu(active_count, latency); + } else { + m_stats->m_num_tex_acesses[m_sid] = + m_stats->m_num_tex_acesses[m_sid] + (double)active_count * latency; } - m_stats->m_active_exu_threads[m_sid]+=active_count; + m_stats->m_active_exu_threads[m_sid] += active_count; m_stats->m_active_exu_warps[m_sid]++; } void inc_const_accesses(unsigned active_count) { - m_stats->m_num_const_acesses[m_sid]=m_stats->m_num_const_acesses[m_sid]+active_count; + m_stats->m_num_const_acesses[m_sid] = + m_stats->m_num_const_acesses[m_sid] + active_count; } void incsfu_stat(unsigned active_count, double latency) { m_stats->m_num_sfu_acesses[m_sid] = - m_stats->m_num_sfu_acesses[m_sid] + (double)active_count*latency; + m_stats->m_num_sfu_acesses[m_sid] + (double)active_count * latency; } void incsp_stat(unsigned active_count, double latency) { m_stats->m_num_sp_acesses[m_sid] = - m_stats->m_num_sp_acesses[m_sid] + (double)active_count*latency; + m_stats->m_num_sp_acesses[m_sid] + (double)active_count * latency; } void incmem_stat(unsigned active_count, double latency) { if (m_config->gpgpu_clock_gated_lanes == false) { m_stats->m_num_mem_acesses[m_sid] = - m_stats->m_num_mem_acesses[m_sid] + (double)active_count*latency + + m_stats->m_num_mem_acesses[m_sid] + (double)active_count * latency + inactive_lanes_accesses_nonsfu(active_count, latency); } else { m_stats->m_num_mem_acesses[m_sid] = - m_stats->m_num_mem_acesses[m_sid] + (double)active_count*latency; + m_stats->m_num_mem_acesses[m_sid] + (double)active_count * latency; } } void incexecstat(warp_inst_t *&inst); @@ -2572,6 +2625,7 @@ class simt_core_cluster { void cache_invalidate(); bool icnt_injection_buffer_full(unsigned size, bool write); void icnt_inject_request_packet(class mem_fetch *mf); + void update_icnt_stats(class mem_fetch *mf); // for perfect memory interface bool response_queue_full() { @@ -2633,6 +2687,50 @@ class exec_simt_core_cluster : public simt_core_cluster { virtual void create_shader_core_ctx(); }; +/** + * @brief SST cluster class + * + */ +class sst_simt_core_cluster : public exec_simt_core_cluster { + public: + sst_simt_core_cluster(class gpgpu_sim *gpu, unsigned cluster_id, + const shader_core_config *config, + const memory_config *mem_config, + class shader_core_stats *stats, + class memory_stats_t *mstats) + : exec_simt_core_cluster(gpu, cluster_id, config, mem_config, stats, + mstats) {} + + /** + * @brief Check if SST memory request injection + * buffer is full by using extern + * function is_SST_buffer_full() + * defined in Balar + * + * @param size + * @param write + * @param type + * @return true + * @return false + */ + bool SST_injection_buffer_full(unsigned size, bool write, + mem_access_type type); + + /** + * @brief Send memory request packets to SST + * memory + * + * @param mf + */ + void icnt_inject_request_packet_to_SST(class mem_fetch *mf); + + /** + * @brief Advance ICNT between core and SST + * + */ + void icnt_cycle_SST(); +}; + class shader_memory_interface : public mem_fetch_interface { public: shader_memory_interface(shader_core_ctx *core, simt_core_cluster *cluster) { @@ -2673,6 +2771,61 @@ class perfect_memory_interface : public mem_fetch_interface { simt_core_cluster *m_cluster; }; +/** + * @brief SST memory interface + * + */ +class sst_memory_interface : public mem_fetch_interface { + public: + sst_memory_interface(shader_core_ctx *core, sst_simt_core_cluster *cluster) { + m_core = core; + m_cluster = cluster; + } + /** + * @brief For constant, inst, tex cache access + * + * @param size + * @param write + * @return true + * @return false + */ + virtual bool full(unsigned size, bool write) const { + assert(false && "Use the full() method with access type instead!"); + return true; + } + + /** + * @brief With SST, the core will direct all mem access except for + * constant, tex, and inst reads to SST mem system + * (i.e. not modeling constant mem right now), thus + * requiring the mem_access_type information to be passed in + * + * @param size + * @param write + * @param type + * @return true + * @return false + */ + bool full(unsigned size, bool write, mem_access_type type) const { + return m_cluster->SST_injection_buffer_full(size, write, type); + } + + /** + * @brief Push memory request to SST memory system and + * update stats + * + * @param mf + */ + virtual void push(mem_fetch *mf) { + m_core->inc_simt_to_mem(mf->get_num_flits(true)); + m_cluster->icnt_inject_request_packet_to_SST(mf); + } + + private: + shader_core_ctx *m_core; + sst_simt_core_cluster *m_cluster; +}; + inline int scheduler_unit::get_sid() const { return m_shader->get_sid(); } #endif /* SHADER_H */ diff --git a/src/gpgpu-sim/shader_trace.h b/src/gpgpu-sim/shader_trace.h index e7486d8..367262c 100644 --- a/src/gpgpu-sim/shader_trace.h +++ b/src/gpgpu-sim/shader_trace.h @@ -38,7 +38,7 @@ #define SCHED_PRINT_STR SHADER_PRINT_STR "Scheduler %d - " #define SHADER_DTRACE(x) \ (DTRACE(x) && \ - (Trace::sampling_core == get_sid() || Trace::sampling_core == -1)) + (Trace::sampling_core == (int)get_sid() || Trace::sampling_core == -1)) // Intended to be called from inside components of a shader core. // Depends on a get_sid() function diff --git a/src/gpgpu-sim/stat-tool.cc b/src/gpgpu-sim/stat-tool.cc index 0513d17..08bbe9e 100644 --- a/src/gpgpu-sim/stat-tool.cc +++ b/src/gpgpu-sim/stat-tool.cc @@ -519,7 +519,7 @@ void thread_insn_span::print_span(FILE *fout) const { fprintf(fout, "%d: ", (int)m_cycle); span_count_map::const_iterator i_sc = m_insn_span_count.begin(); for (; i_sc != m_insn_span_count.end(); ++i_sc) { - fprintf(fout, "%d ", i_sc->first); + fprintf(fout, "%llx ", i_sc->first); } fprintf(fout, "\n"); } diff --git a/src/gpgpusim_entrypoint.cc b/src/gpgpusim_entrypoint.cc index f4287d8..e2b711e 100644 --- a/src/gpgpusim_entrypoint.cc +++ b/src/gpgpusim_entrypoint.cc @@ -43,6 +43,21 @@ static int sg_argc = 3; static const char *sg_argv[] = {"", "-config", "gpgpusim.config"}; +// Help funcs to avoid multiple '->' for SST +GPGPUsim_ctx *GPGPUsim_ctx_ptr() { return GPGPU_Context()->the_gpgpusim; } + +class sst_gpgpu_sim *g_the_gpu() { + return static_cast<sst_gpgpu_sim *>(GPGPUsim_ctx_ptr()->g_the_gpu); +} + +class stream_manager *g_stream_manager() { + return GPGPUsim_ctx_ptr()->g_stream_manager; +} + +// SST callback +extern void SST_callback_cudaThreadSynchronize_done(); +__attribute__((weak)) void SST_callback_cudaThreadSynchronize_done() {} + void *gpgpu_sim_thread_sequential(void *ctx_ptr) { gpgpu_context *ctx = (gpgpu_context *)ctx_ptr; // at most one kernel running at a time @@ -57,7 +72,8 @@ void *gpgpu_sim_thread_sequential(void *ctx_ptr) { ctx->the_gpgpusim->g_the_gpu->cycle(); ctx->the_gpgpusim->g_the_gpu->deadlock_check(); } - ctx->the_gpgpusim->g_the_gpu->print_stats(); + ctx->the_gpgpusim->g_the_gpu->print_stats( + ctx->the_gpgpusim->g_the_gpu->last_streamID); ctx->the_gpgpusim->g_the_gpu->update_stats(); ctx->print_simulation_time(); } @@ -144,7 +160,8 @@ void *gpgpu_sim_thread_concurrent(void *ctx_ptr) { fflush(stdout); } if (sim_cycles) { - ctx->the_gpgpusim->g_the_gpu->print_stats(); + ctx->the_gpgpusim->g_the_gpu->print_stats( + ctx->the_gpgpusim->g_the_gpu->last_streamID); ctx->the_gpgpusim->g_the_gpu->update_stats(); ctx->print_simulation_time(); } @@ -167,6 +184,75 @@ void *gpgpu_sim_thread_concurrent(void *ctx_ptr) { return NULL; } +bool sst_sim_cycles = false; + +bool SST_Cycle() { + // Check if Synchronize is done when SST previously requested + // cudaThreadSynchronize + if (GPGPU_Context()->requested_synchronize && + ((g_stream_manager()->empty() && !GPGPUsim_ctx_ptr()->g_sim_active) || + GPGPUsim_ctx_ptr()->g_sim_done)) { + SST_callback_cudaThreadSynchronize_done(); + GPGPU_Context()->requested_synchronize = false; + } + + if (g_stream_manager()->empty_protected() && + !GPGPUsim_ctx_ptr()->g_sim_done && !g_the_gpu()->active()) { + GPGPUsim_ctx_ptr()->g_sim_active = false; + // printf("stream is empty %d \n", g_stream_manager->empty()); + return false; + } + + if (g_stream_manager()->operation(&sst_sim_cycles) && + !g_the_gpu()->active()) { + if (sst_sim_cycles) { + sst_sim_cycles = false; + } + return false; + } + + // printf("GPGPU-Sim: Give GPU Cycle\n"); + GPGPUsim_ctx_ptr()->g_sim_active = true; + + // functional simulation + if (g_the_gpu()->is_functional_sim()) { + kernel_info_t *kernel = g_the_gpu()->get_functional_kernel(); + assert(kernel); + GPGPUsim_ctx_ptr()->gpgpu_ctx->func_sim->gpgpu_cuda_ptx_sim_main_func( + *kernel); + g_the_gpu()->finish_functional_sim(kernel); + } + + // performance simulation + if (g_the_gpu()->active()) { + g_the_gpu()->SST_cycle(); + sst_sim_cycles = true; + g_the_gpu()->deadlock_check(); + } else { + if (g_the_gpu()->cycle_insn_cta_max_hit()) { + g_stream_manager()->stop_all_running_kernels(); + GPGPUsim_ctx_ptr()->g_sim_done = true; + GPGPUsim_ctx_ptr()->g_sim_active = false; + GPGPUsim_ctx_ptr()->break_limit = true; + } + } + + if (!g_the_gpu()->active()) { + g_the_gpu()->print_stats(GPGPUsim_ctx_ptr()->g_the_gpu->last_streamID); + g_the_gpu()->update_stats(); + GPGPU_Context()->print_simulation_time(); + } + + if (GPGPUsim_ctx_ptr()->break_limit) { + printf( + "GPGPU-Sim: ** break due to reaching the maximum cycles (or " + "instructions) **\n"); + return true; + } + + return false; +} + void gpgpu_context::synchronize() { printf("GPGPU-Sim: synchronize waiting for inactive GPU simulation\n"); the_gpgpusim->g_stream_manager->print(stdout); @@ -185,6 +271,27 @@ void gpgpu_context::synchronize() { // sem_post(&g_sim_signal_start); } +bool gpgpu_context::synchronize_check() { + // printf("GPGPU-Sim: synchronize checking for inactive GPU simulation\n"); + requested_synchronize = true; + the_gpgpusim->g_stream_manager->print(stdout); + fflush(stdout); + // sem_wait(&g_sim_signal_finish); + bool done = false; + pthread_mutex_lock(&(the_gpgpusim->g_sim_lock)); + done = (the_gpgpusim->g_stream_manager->empty() && + !the_gpgpusim->g_sim_active) || + the_gpgpusim->g_sim_done; + pthread_mutex_unlock(&(the_gpgpusim->g_sim_lock)); + if (done) { + printf( + "GPGPU-Sim: synchronize checking: detected inactive GPU simulation " + "thread\n"); + } + fflush(stdout); + return done; +} + void gpgpu_context::exit_simulation() { the_gpgpusim->g_sim_done = true; printf("GPGPU-Sim: exit_simulation called\n"); @@ -218,8 +325,14 @@ gpgpu_sim *gpgpu_context::gpgpu_ptx_sim_init_perf() { assert(setlocale(LC_NUMERIC, "C")); the_gpgpusim->g_the_gpu_config->init(); - the_gpgpusim->g_the_gpu = - new exec_gpgpu_sim(*(the_gpgpusim->g_the_gpu_config), this); + if (the_gpgpusim->g_the_gpu_config->is_SST_mode()) { + // Create SST specific GPGPUSim + the_gpgpusim->g_the_gpu = + new sst_gpgpu_sim(*(the_gpgpusim->g_the_gpu_config), this); + } else { + the_gpgpusim->g_the_gpu = + new exec_gpgpu_sim(*(the_gpgpusim->g_the_gpu_config), this); + } the_gpgpusim->g_stream_manager = new stream_manager( (the_gpgpusim->g_the_gpu), func_sim->g_cuda_launch_blocking); @@ -235,12 +348,17 @@ gpgpu_sim *gpgpu_context::gpgpu_ptx_sim_init_perf() { void gpgpu_context::start_sim_thread(int api) { if (the_gpgpusim->g_sim_done) { the_gpgpusim->g_sim_done = false; - if (api == 1) { - pthread_create(&(the_gpgpusim->g_simulation_thread), NULL, - gpgpu_sim_thread_concurrent, (void *)this); + if (the_gpgpusim->g_the_gpu_config->is_SST_mode()) { + // Do not create concurrent thread in SST mode + g_the_gpu()->init(); } else { - pthread_create(&(the_gpgpusim->g_simulation_thread), NULL, - gpgpu_sim_thread_sequential, (void *)this); + if (api == 1) { + pthread_create(&(the_gpgpusim->g_simulation_thread), NULL, + gpgpu_sim_thread_concurrent, (void *)this); + } else { + pthread_create(&(the_gpgpusim->g_simulation_thread), NULL, + gpgpu_sim_thread_sequential, (void *)this); + } } } } @@ -264,8 +382,13 @@ void gpgpu_context::print_simulation_time() { const unsigned cycles_per_sec = (unsigned)(the_gpgpusim->g_the_gpu->gpu_tot_sim_cycle / difference); printf("gpgpu_simulation_rate = %u (cycle/sec)\n", cycles_per_sec); - printf("gpgpu_silicon_slowdown = %ux\n", - the_gpgpusim->g_the_gpu->shader_clock() * 1000 / cycles_per_sec); + + if (cycles_per_sec == 0) { + printf("gpgpu_silicon_slowdown = Nan\n"); + } else { + printf("gpgpu_silicon_slowdown = %ux\n", + the_gpgpusim->g_the_gpu->shader_clock() * 1000 / cycles_per_sec); + } fflush(stdout); } diff --git a/src/intersim2/CMakeLists.txt b/src/intersim2/CMakeLists.txt new file mode 100644 index 0000000..c3da1b1 --- /dev/null +++ b/src/intersim2/CMakeLists.txt @@ -0,0 +1,106 @@ +option(GPGPUSIM_INTERSIM_STANDALONE "Whether to also build intersim in standalone mode" OFF) + +# Specify Flex and Bison target +BISON_TARGET(intersim_config_parser config.y ${CMAKE_CURRENT_BINARY_DIR}/y.tab.c + COMPILE_FLAGS "-y -d --file-prefix=${CMAKE_CURRENT_BINARY_DIR}/y") +FLEX_TARGET(intersim_config_lexer config.l ${CMAKE_CURRENT_BINARY_DIR}/lex.yy.c) +ADD_FLEX_BISON_DEPENDENCY(intersim_config_lexer intersim_config_parser) + +# Set generated source files to CXX +set_source_files_properties(${BISON_intersim_config_parser_OUTPUT_SOURCE} + ${FLEX_intersim_config_lexer_OUTPUTS} + PROPERTIES LANGUAGE CXX) + +# Create booksim or libintersim.a +# Shared include path +list(APPEND intersim_INC ${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/allocators + ${CMAKE_CURRENT_SOURCE_DIR}/arbiters + ${CMAKE_CURRENT_SOURCE_DIR}/networks + ${CMAKE_CURRENT_SOURCE_DIR}/power + ${CMAKE_CURRENT_SOURCE_DIR}/routers + ${PROJECT_SOURCE_DIR}/src) + +# Shared source files +list(APPEND intersim_SRC + ${BISON_intersim_config_parser_OUTPUT_SOURCE} + ${FLEX_intersim_config_lexer_OUTPUTS} + allocators/allocator.cpp + allocators/islip.cpp + allocators/loa.cpp + allocators/maxsize.cpp + allocators/pim.cpp + allocators/selalloc.cpp + allocators/separable.cpp + allocators/separable_input_first.cpp + allocators/separable_output_first.cpp + allocators/wavefront.cpp + arbiters/arbiter.cpp + arbiters/matrix_arb.cpp + arbiters/prio_arb.cpp + arbiters/roundrobin_arb.cpp + arbiters/tree_arb.cpp + batchtrafficmanager.cpp + booksim_config.cpp + buffer.cpp + buffer_state.cpp + config_utils.cpp + credit.cpp + flitchannel.cpp + flit.cpp + gputrafficmanager.cpp + injection.cpp + interconnect_interface.cpp + intersim_config.cpp + main.cpp + misc_utils.cpp + module.cpp + networks/anynet.cpp + networks/cmesh.cpp + networks/dragonfly.cpp + networks/fattree.cpp + networks/flatfly_onchip.cpp + networks/fly.cpp + networks/kncube.cpp + networks/network.cpp + networks/qtree.cpp + networks/tree4.cpp + outputset.cpp + packet_reply_info.cpp + power/buffer_monitor.cpp + power/power_module.cpp + power/switch_monitor.cpp + rng_double_wrapper.cpp + rng_wrapper.cpp + routefunc.cpp + routers/chaos_router.cpp + routers/event_router.cpp + routers/iq_router.cpp + routers/router.cpp + stats.cpp + traffic.cpp + trafficmanager.cpp + vc.cpp) + +# If standalone, also build for it +if(GPGPUSIM_INTERSIM_STANDALONE) + list(REMOVE_ITEM ${intersim_SRC} interconnect_interface.cpp) + add_executable(booksim ${intersim_SRC}) + target_include_directories(booksim PUBLIC + ${intersim_INC}) + target_include_directories(booksim PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) + target_include_directories(booksim PUBLIC ${CUDAToolkit_INCLUDE_DIRS}) + # Remove globally set TRACING_ON flag + target_compile_options(booksim PRIVATE -UTRACING_ON) +endif() + +# Specify sources for libintersim.a +add_library(intersim STATIC ${intersim_SRC}) +target_include_directories(intersim PUBLIC + ${intersim_INC} + ${PROJECT_SOURCE_DIR}/src/gpgpu-sim) +target_include_directories(intersim PRIVATE ${CMAKE_CURRENT_BINARY_DIR}) +target_include_directories(intersim PUBLIC ${CUDAToolkit_INCLUDE_DIRS}) +target_compile_definitions(intersim PRIVATE CREATE_LIBRARY) +# Remove globally set TRACING_ON flag +target_compile_options(intersim PRIVATE -UTRACING_ON) diff --git a/src/intersim2/Makefile b/src/intersim2/Makefile index 3eeeb70..a7485e2 100644 --- a/src/intersim2/Makefile +++ b/src/intersim2/Makefile @@ -28,7 +28,7 @@ # Makefile # CXX = g++ -CC = gcc +CC = g++ CREATE_LIBRARY ?= 0 INTERFACE = interconnect_interface.cpp DEBUG ?= 0 @@ -136,10 +136,10 @@ depend: makedepend -f$(OBJDIR)/Makefile.makedepend -I$(INCPATH) -p$(OBJDIR)/ $(ALL_SRCS) 2> /dev/null ${LEX_OBJS}: $(OBJDIR)/lex.yy.c $(OBJDIR)/y.tab.h - $(CC) $(CPPFLAGS) -c $< -o $@ + $(CC) -Wno-unused-function $(CPPFLAGS) -c $< -o $@ ${YACC_OBJS}: $(OBJDIR)/y.tab.c $(OBJDIR)/y.tab.h - $(CC) $(CPPFLAGS) -c $< -o $@ + $(CC) -Wno-unused-function $(CPPFLAGS) -c $< -o $@ ${OBJDIR}/%.o: %.cpp $(CXX) $(CPPFLAGS) -c $< -o $@ diff --git a/src/intersim2/config_utils.cpp b/src/intersim2/config_utils.cpp index fad5fce..a896a93 100644 --- a/src/intersim2/config_utils.cpp +++ b/src/intersim2/config_utils.cpp @@ -199,27 +199,27 @@ Configuration * Configuration::GetTheConfig() //============================================================ -extern "C" void config_error( char const * msg, int lineno ) +void config_error( char * msg, int lineno ) { Configuration::GetTheConfig( )->ParseError( msg, lineno ); } -extern "C" void config_assign_string( char const * field, char const * value ) + void config_assign_string( char const * field, char const * value ) { Configuration::GetTheConfig()->Assign(field, value); } -extern "C" void config_assign_int( char const * field, int value ) +void config_assign_int( char const * field, int value ) { Configuration::GetTheConfig()->Assign(field, value); } -extern "C" void config_assign_float( char const * field, double value ) +void config_assign_float( char const * field, double value ) { Configuration::GetTheConfig()->Assign(field, value); } -extern "C" int config_input(char * line, int max_size) +int config_input(char * line, int max_size) { return Configuration::GetTheConfig()->Input(line, max_size); } diff --git a/src/intersim2/config_utils.hpp b/src/intersim2/config_utils.hpp index de3343b..1d960b6 100644 --- a/src/intersim2/config_utils.hpp +++ b/src/intersim2/config_utils.hpp @@ -35,7 +35,7 @@ #include<map> #include<vector> -extern "C" int yyparse(); +int yyparse(); class Configuration { static Configuration * theConfig; diff --git a/src/intersim2/interconnect_interface.cpp b/src/intersim2/interconnect_interface.cpp index 1e1a2d7..438852e 100644 --- a/src/intersim2/interconnect_interface.cpp +++ b/src/intersim2/interconnect_interface.cpp @@ -200,7 +200,7 @@ void InterconnectInterface::Push(unsigned input_deviceID, unsigned output_device void* InterconnectInterface::Pop(unsigned deviceID) { int icntID = _node_map[deviceID]; -#if DEBUG +#if 0 cout<<"Call interconnect POP " << output<<endl; #endif diff --git a/src/intersim2/networks/anynet.cpp b/src/intersim2/networks/anynet.cpp index 4db1dfb..d7c6f22 100644 --- a/src/intersim2/networks/anynet.cpp +++ b/src/intersim2/networks/anynet.cpp @@ -491,7 +491,7 @@ void AnyNet::readFile(){ } sort(node_check.begin(), node_check.end()); for(size_t i = 0; i<node_check.size(); i++){ - if(node_check[i] != i){ + if(node_check[i] != (int)i){ cout<<"Anynet:booksim trafficmanager assumes sequential node numbering starting at 0\n"; assert(false); } diff --git a/src/intersim2/networks/dragonfly.cpp b/src/intersim2/networks/dragonfly.cpp index 01a2281..f5b637e 100644 --- a/src/intersim2/networks/dragonfly.cpp +++ b/src/intersim2/networks/dragonfly.cpp @@ -111,7 +111,7 @@ int dragonfly_port(int rID, int source, int dest){ int dest_grp_ID = int(dest/_grp_num_nodes); int grp_output=-1; int grp_RID=-1; - int group_dest=-1; + // int group_dest=-1; //which router within this group the packet needs to go to if (dest_grp_ID == grp_ID) { @@ -123,7 +123,7 @@ int dragonfly_port(int rID, int source, int dest){ grp_output = dest_grp_ID - 1; } grp_RID = int(grp_output /gP) + grp_ID * _grp_num_routers; - group_dest = grp_RID * gP; + // group_dest = grp_RID * gP; } //At the last hop @@ -221,7 +221,7 @@ void DragonFlyNew::_BuildNet( const Configuration &config ) int _input=-1; int _dim_ID=-1; int _num_ports_per_switch=-1; - int _dim_size=-1; + // int _dim_size=-1; int c; ostringstream router_name; @@ -314,7 +314,7 @@ void DragonFlyNew::_BuildNet( const Configuration &config ) // intra-group GROUP channels for ( int dim = 0; dim < _n; ++dim ) { - _dim_size = powi(_k,dim); + // _dim_size = powi(_k,dim); _dim_ID = ((int) (node / ( powi(_p, dim)))); @@ -356,16 +356,16 @@ void DragonFlyNew::_BuildNet( const Configuration &config ) // add INPUT channels -- "optical" channels connecting the groups - int _grp_num_routers; + // int _grp_num_routers; int grp_output; - int grp_ID2; + // int grp_ID2; for ( int cnt = 0; cnt < _p; ++cnt ) { // _dim_ID grp_output = _dim_ID* _p + cnt; - _grp_num_routers = powi(_k, _n-1); - grp_ID2 = (int) ((grp_ID - 1) / (_k - 1)); + // _grp_num_routers = powi(_k, _n-1); + // grp_ID2 = (int) ((grp_ID - 1) / (_k - 1)); if ( grp_ID > grp_output) { @@ -495,8 +495,8 @@ void ugal_dragonflynew( const Router *r, const Flit *f, int in_channel, int debug = f->watch; int out_port = -1; int out_vc = 0; - int min_queue_size, min_hopcnt; - int nonmin_queue_size, nonmin_hopcnt; + int min_queue_size; //, min_hopcnt; + int nonmin_queue_size; //, nonmin_hopcnt; int intm_grp_ID; int intm_rID; @@ -523,13 +523,13 @@ void ugal_dragonflynew( const Router *r, const Flit *f, int in_channel, f->ph = 1; } else { //congestion metrics using queue length, obtained by GetUsedCredit() - min_hopcnt = dragonflynew_hopcnt(f->src, f->dest); + // min_hopcnt = dragonflynew_hopcnt(f->src, f->dest); min_router_output = dragonfly_port(rID, f->src, f->dest); min_queue_size = max(r->GetUsedCredit(min_router_output), 0) ; - nonmin_hopcnt = dragonflynew_hopcnt(f->src, f->intm) + - dragonflynew_hopcnt(f->intm,f->dest); + // nonmin_hopcnt = dragonflynew_hopcnt(f->src, f->intm) + + // dragonflynew_hopcnt(f->intm,f->dest); nonmin_router_output = dragonfly_port(rID, f->src, f->intm); nonmin_queue_size = max(r->GetUsedCredit(nonmin_router_output), 0); diff --git a/src/intersim2/networks/flatfly_onchip.cpp b/src/intersim2/networks/flatfly_onchip.cpp index fd17c1a..df43371 100644 --- a/src/intersim2/networks/flatfly_onchip.cpp +++ b/src/intersim2/networks/flatfly_onchip.cpp @@ -1204,7 +1204,7 @@ void ugal_pni_flatfly_onchip( const Router *r, const Flit *f, int in_channel, int find_distance (int src, int dest) { int dist = 0; int _dim = gN; - int _dim_size; + // int _dim_size; int src_tmp= (int) src / gC; int dest_tmp = (int) dest / gC; @@ -1212,7 +1212,7 @@ int find_distance (int src, int dest) { // cout << " HOP CNT between src: " << src << " dest: " << dest; for (int d=0;d < _dim; d++) { - _dim_size = powi(gK, d )*gC; + // _dim_size = powi(gK, d )*gC; //if ((int)(src / _dim_size) != (int)(dest / _dim_size)) // dist++; src_id = src_tmp % gK; diff --git a/src/intersim2/networks/kncube.cpp b/src/intersim2/networks/kncube.cpp index 03e13e7..178c905 100644 --- a/src/intersim2/networks/kncube.cpp +++ b/src/intersim2/networks/kncube.cpp @@ -231,7 +231,7 @@ void KNCube::InsertRandomFaults( const Configuration &config ) int num_fails; unsigned long prev_seed; - int node, chan; + int node, chan = 0; int i, j, t, n, c; bool available; diff --git a/src/intersim2/networks/qtree.cpp b/src/intersim2/networks/qtree.cpp index 7214947..37d3d7c 100644 --- a/src/intersim2/networks/qtree.cpp +++ b/src/intersim2/networks/qtree.cpp @@ -84,7 +84,7 @@ void QTree::_BuildNet( const Configuration& config ) { ostringstream routerName; - int h, r, pos, port; + int h, r = 0 , pos, port; for (h = 0; h < _n; h++) { for (pos = 0 ; pos < powi( _k, h ) ; ++pos ) { diff --git a/src/intersim2/vc.cpp b/src/intersim2/vc.cpp index 94e8c6b..4c94445 100644 --- a/src/intersim2/vc.cpp +++ b/src/intersim2/vc.cpp @@ -82,7 +82,7 @@ void VC::AddFlit( Flit *f ) assert(f); if(_expected_pid >= 0) { - if(f->pid != _expected_pid) { + if((long long int)f->pid != _expected_pid) { ostringstream err; err << "Received flit " << f->id << " with unexpected packet ID: " << f->pid << " (expected: " << _expected_pid << ")"; diff --git a/src/stream_manager.cc b/src/stream_manager.cc index e99bf87..58c2ec4 100644 --- a/src/stream_manager.cc +++ b/src/stream_manager.cc @@ -34,6 +34,16 @@ unsigned CUstream_st::sm_next_stream_uid = 0; +// SST memcpy callbacks +extern void SST_callback_memcpy_H2D_done(); +extern void SST_callback_memcpy_D2H_done(); +extern void SST_callback_memcpy_to_symbol_done(); +extern void SST_callback_memcpy_from_symbol_done(); +__attribute__((weak)) void SST_callback_memcpy_H2D_done() {} +__attribute__((weak)) void SST_callback_memcpy_D2H_done() {} +__attribute__((weak)) void SST_callback_memcpy_to_symbol_done() {} +__attribute__((weak)) void SST_callback_memcpy_from_symbol_done() {} + CUstream_st::CUstream_st() { m_pending = false; m_uid = sm_next_stream_uid++; @@ -122,11 +132,13 @@ bool stream_operation::do_operation(gpgpu_sim *gpu) { if (g_debug_execution >= 3) printf("memcpy host-to-device\n"); gpu->memcpy_to_gpu(m_device_address_dst, m_host_address_src, m_cnt); m_stream->record_next_done(); + if (gpu->is_SST_mode()) SST_callback_memcpy_H2D_done(); break; case stream_memcpy_device_to_host: if (g_debug_execution >= 3) printf("memcpy device-to-host\n"); gpu->memcpy_from_gpu(m_host_address_dst, m_device_address_src, m_cnt); m_stream->record_next_done(); + if (gpu->is_SST_mode()) SST_callback_memcpy_D2H_done(); break; case stream_memcpy_device_to_device: if (g_debug_execution >= 3) printf("memcpy device-to-device\n"); @@ -138,12 +150,14 @@ bool stream_operation::do_operation(gpgpu_sim *gpu) { gpu->gpgpu_ctx->func_sim->gpgpu_ptx_sim_memcpy_symbol( m_symbol, m_host_address_src, m_cnt, m_offset, 1, gpu); m_stream->record_next_done(); + if (gpu->is_SST_mode()) SST_callback_memcpy_to_symbol_done(); break; case stream_memcpy_from_symbol: if (g_debug_execution >= 3) printf("memcpy from symbol\n"); gpu->gpgpu_ctx->func_sim->gpgpu_ptx_sim_memcpy_symbol( m_symbol, m_host_address_dst, m_cnt, m_offset, 0, gpu); m_stream->record_next_done(); + if (gpu->is_SST_mode()) SST_callback_memcpy_from_symbol_done(); break; case stream_kernel_launch: if (m_sim_mode) { // Functional Sim @@ -227,6 +241,8 @@ void stream_operation::print(FILE *fp) const { case stream_no_op: fprintf(fp, "no-op"); break; + default: + break; } } @@ -300,6 +316,14 @@ bool stream_manager::register_finished_kernel(unsigned grid_uid) { void stream_manager::stop_all_running_kernels() { pthread_mutex_lock(&m_lock); + std::vector<unsigned long long> finished_streams; + std::vector<kernel_info_t *> running_kernels = m_gpu->get_running_kernels(); + for (kernel_info_t *k : running_kernels) { + if (k != NULL) { + finished_streams.push_back(k->get_streamID()); + } + } + // Signal m_gpu to stop all running kernels m_gpu->stop_all_running_kernels(); @@ -310,7 +334,9 @@ void stream_manager::stop_all_running_kernels() { } // If any kernels completed, print out the current stats - if (count > 0) m_gpu->print_stats(); + for (unsigned long long streamID : finished_streams) { + m_gpu->print_stats(streamID); + } pthread_mutex_unlock(&m_lock); } @@ -460,7 +486,7 @@ void stream_manager::push(stream_operation op) { } if (g_debug_execution >= 3) print_impl(stdout); pthread_mutex_unlock(&m_lock); - if (m_cuda_launch_blocking || stream == NULL) { + if (!m_gpu->is_SST_mode() && (m_cuda_launch_blocking || stream == NULL)) { unsigned int wait_amount = 100; unsigned int wait_cap = 100000; // 100ms while (!empty()) { diff --git a/src/stream_manager.h b/src/stream_manager.h index afcbb0e..561f54b 100644 --- a/src/stream_manager.h +++ b/src/stream_manager.h @@ -73,7 +73,7 @@ struct CUevent_st { int m_uid; bool m_blocking; bool m_done; - int m_updates; + unsigned int m_updates; unsigned int m_issued; time_t m_wallclock; double m_gpu_tot_sim_cycle; diff --git a/version.in b/version.in new file mode 100644 index 0000000..2935c6f --- /dev/null +++ b/version.in @@ -0,0 +1 @@ +const char *g_gpgpusim_build_string="@GPGPUSIM_BUILD_STRING@";
\ No newline at end of file diff --git a/version_detection.mk b/version_detection.mk index ee71a62..0bf3095 100644 --- a/version_detection.mk +++ b/version_detection.mk @@ -32,7 +32,7 @@ else GPGPUSIM_VERSION=$(shell cat $(GPGPUSIM_ROOT)/version | awk '/Version/ {print $$8}' ) #Detect Git branch and commit # -GIT_COMMIT := $(shell git log -n 1 | head -1 | sed -re 's/commit (.*)/\1/') +GIT_COMMIT := $(shell git log --abbrev-commit -n 1 | head -1 | sed -re 's/commit (.*)/\1/') GIT_FILES_CHANGED_A:=$(shell git diff --numstat | wc | sed -re 's/^\s+([0-9]+).*/\1./') GIT_FILES_CHANGED:= $(GIT_FILES_CHANGED_A)$(shell git diff --numstat --cached | wc | sed -re 's/^\s+([0-9]+).*/\1/') GPGPUSIM_BUILD := gpgpu-sim_git-commit-$(GIT_COMMIT)_modified_$(GIT_FILES_CHANGED) @@ -43,7 +43,7 @@ CUDA_VERSION_STRING:=$(shell $(CUDA_INSTALL_PATH)/bin/nvcc --version | awk '/rel CUDART_VERSION:=$(shell echo $(CUDA_VERSION_STRING) | sed 's/\./ /' | awk '{printf("%02u%02u", 10*int($$1), 10*$$2);}') # Detect GCC Version -CC_VERSION := $(shell gcc --version | head -1 | awk '{for(i=1;i<=NF;i++){ if(match($$i,/^[0-9]\.[0-9]\.[0-9]$$/)) {print $$i; exit 0 }}}') +CC_VERSION := $(shell gcc --version | head -1 | awk '{for(i=1;i<=NF;i++){ if(match($$i,/^[0-9]+\.[0-9]+\.[0-9]+$$/)) {print $$i; exit 0 }}}') # Detect Support for C++11 (C++0x) from GCC Version -GNUC_CPP0X := $(shell gcc --version | perl -ne 'if (/gcc\s+\(.*\)\s+([0-9.]+)/){ if($$1 >= 4.3) {$$n=1} else {$$n=0;} } END { print $$n; }') +GNUC_CPP0X := 1 |
