diff options
Diffstat (limited to 'src/gpgpu-sim')
| -rw-r--r-- | src/gpgpu-sim/CMakeLists.txt | 36 | ||||
| -rw-r--r-- | src/gpgpu-sim/addrdec.cc | 4 | ||||
| -rw-r--r-- | src/gpgpu-sim/dram.cc | 100 | ||||
| -rw-r--r-- | src/gpgpu-sim/dram.h | 12 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.cc | 581 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-cache.h | 99 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.cc | 504 | ||||
| -rw-r--r-- | src/gpgpu-sim/gpu-sim.h | 187 | ||||
| -rw-r--r-- | src/gpgpu-sim/l2cache.cc | 46 | ||||
| -rw-r--r-- | src/gpgpu-sim/l2cache.h | 19 | ||||
| -rw-r--r-- | src/gpgpu-sim/local_interconnect.cc | 18 | ||||
| -rw-r--r-- | src/gpgpu-sim/mem_fetch.cc | 29 | ||||
| -rw-r--r-- | src/gpgpu-sim/mem_fetch.h | 12 | ||||
| -rw-r--r-- | src/gpgpu-sim/mem_latency_stat.cc | 17 | ||||
| -rw-r--r-- | src/gpgpu-sim/power_interface.cc | 636 | ||||
| -rw-r--r-- | src/gpgpu-sim/power_interface.h | 32 | ||||
| -rw-r--r-- | src/gpgpu-sim/power_stat.cc | 530 | ||||
| -rw-r--r-- | src/gpgpu-sim/power_stat.h | 862 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.cc | 625 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader.h | 657 | ||||
| -rw-r--r-- | src/gpgpu-sim/shader_trace.h | 2 | ||||
| -rw-r--r-- | src/gpgpu-sim/stat-tool.cc | 2 |
22 files changed, 3168 insertions, 1842 deletions
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"); } |
