summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/l2cache.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/gpgpu-sim/l2cache.cc')
-rw-r--r--src/gpgpu-sim/l2cache.cc1342
1 files changed, 651 insertions, 691 deletions
diff --git a/src/gpgpu-sim/l2cache.cc b/src/gpgpu-sim/l2cache.cc
index 7fdb5a3..fb4ce32 100644
--- a/src/gpgpu-sim/l2cache.cc
+++ b/src/gpgpu-sim/l2cache.cc
@@ -7,16 +7,14 @@
//
// Redistributions of source code must retain the above copyright notice, this
// list of conditions and the following disclaimer.
-// Redistributions in binary form must reproduce the above copyright notice,
-// this
+// 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.
// Neither the name of The University of British Columbia nor the names of its
// contributors may be used to endorse or promote products derived from this
// software without specific prior written permission.
//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
-// AND
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
@@ -27,835 +25,797 @@
// OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#include <stdio.h>
#include <stdlib.h>
+#include <stdio.h>
#include <string.h>
#include <list>
#include <set>
-#include "../abstract_hardware_model.h"
#include "../option_parser.h"
-#include "../statwrapper.h"
+#include "mem_fetch.h"
#include "dram.h"
#include "gpu-cache.h"
-#include "gpu-sim.h"
#include "histogram.h"
#include "l2cache.h"
-#include "l2cache_trace.h"
-#include "mem_fetch.h"
-#include "mem_latency_stat.h"
+#include "../statwrapper.h"
+#include "../abstract_hardware_model.h"
+#include "gpu-sim.h"
#include "shader.h"
+#include "mem_latency_stat.h"
+#include "l2cache_trace.h"
+
-mem_fetch *partition_mf_allocator::alloc(new_addr_type addr,
- mem_access_type type, unsigned size,
- bool wr,
- unsigned long long cycle) 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);
- return mf;
+mem_fetch * partition_mf_allocator::alloc(new_addr_type addr, mem_access_type type, unsigned size, bool wr, unsigned long long cycle ) 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);
+ return mf;
}
-memory_partition_unit::memory_partition_unit(unsigned partition_id,
- const memory_config *config,
- class memory_stats_t *stats,
- class gpgpu_sim *gpu)
- : m_id(partition_id),
- m_config(config),
- m_stats(stats),
- m_arbitration_metadata(config),
- m_gpu(gpu) {
- m_dram = new dram_t(m_id, m_config, m_stats, this, gpu);
+memory_partition_unit::memory_partition_unit( unsigned partition_id,
+ const memory_config *config,
+ class memory_stats_t *stats,
+ class gpgpu_sim* gpu)
+: m_id(partition_id), m_config(config), m_stats(stats), m_arbitration_metadata(config), m_gpu(gpu)
+{
+ m_dram = new dram_t(m_id,m_config,m_stats,this,gpu);
+
+ m_sub_partition = new memory_sub_partition*[m_config->m_n_sub_partition_per_memory_channel];
+ for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel; p++) {
+ unsigned sub_partition_id = m_id * m_config->m_n_sub_partition_per_memory_channel + p;
+ m_sub_partition[p] = new memory_sub_partition(sub_partition_id, m_config, stats, gpu);
+ }
- m_sub_partition = new memory_sub_partition
- *[m_config->m_n_sub_partition_per_memory_channel];
- for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel;
- p++) {
- unsigned sub_partition_id =
- m_id * m_config->m_n_sub_partition_per_memory_channel + p;
- m_sub_partition[p] =
- new memory_sub_partition(sub_partition_id, m_config, stats, gpu);
- }
}
-void memory_partition_unit::handle_memcpy_to_gpu(
- size_t addr, unsigned global_subpart_id, mem_access_sector_mask_t mask) {
- unsigned p = global_sub_partition_id_to_local_id(global_subpart_id);
- std::string mystring = mask.to_string<char, std::string::traits_type,
- std::string::allocator_type>();
- MEMPART_DPRINTF(
- "Copy Engine Request Received For Address=%zx, local_subpart=%u, "
- "global_subpart=%u, sector_mask=%s \n",
- addr, p, global_subpart_id, mystring.c_str());
- m_sub_partition[p]->force_l2_tag_update(
- addr, m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle, mask);
+void memory_partition_unit::handle_memcpy_to_gpu( size_t addr, unsigned global_subpart_id, mem_access_sector_mask_t mask )
+{
+ unsigned p = global_sub_partition_id_to_local_id(global_subpart_id);
+ std::string mystring =
+ mask.to_string<char,std::string::traits_type,std::string::allocator_type>();
+ MEMPART_DPRINTF("Copy Engine Request Received For Address=%zx, local_subpart=%u, global_subpart=%u, sector_mask=%s \n", addr, p, global_subpart_id, mystring.c_str());
+ m_sub_partition[p]->force_l2_tag_update(addr,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle, mask);
}
-memory_partition_unit::~memory_partition_unit() {
- delete m_dram;
- for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel;
- p++) {
- delete m_sub_partition[p];
- }
- delete[] m_sub_partition;
+memory_partition_unit::~memory_partition_unit()
+{
+ delete m_dram;
+ for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel; p++) {
+ delete m_sub_partition[p];
+ }
+ delete[] m_sub_partition;
}
-memory_partition_unit::arbitration_metadata::arbitration_metadata(
- const memory_config *config)
- : m_last_borrower(config->m_n_sub_partition_per_memory_channel - 1),
- m_private_credit(config->m_n_sub_partition_per_memory_channel, 0),
- m_shared_credit(0) {
- // each sub partition get at least 1 credit for forward progress
- // the rest is shared among with other partitions
- m_private_credit_limit = 1;
- m_shared_credit_limit = config->gpgpu_frfcfs_dram_sched_queue_size +
- config->gpgpu_dram_return_queue_size -
- (config->m_n_sub_partition_per_memory_channel - 1);
- if (config->seperate_write_queue_enabled)
- m_shared_credit_limit += config->gpgpu_frfcfs_dram_write_queue_size;
- if (config->gpgpu_frfcfs_dram_sched_queue_size == 0 or
- config->gpgpu_dram_return_queue_size == 0) {
- m_shared_credit_limit =
- 0; // no limit if either of the queue has no limit in size
- }
- assert(m_shared_credit_limit >= 0);
+memory_partition_unit::arbitration_metadata::arbitration_metadata(const memory_config *config)
+: m_last_borrower(config->m_n_sub_partition_per_memory_channel - 1),
+ m_private_credit(config->m_n_sub_partition_per_memory_channel, 0),
+ m_shared_credit(0)
+{
+ // each sub partition get at least 1 credit for forward progress
+ // the rest is shared among with other partitions
+ m_private_credit_limit = 1;
+ m_shared_credit_limit = config->gpgpu_frfcfs_dram_sched_queue_size
+ + config->gpgpu_dram_return_queue_size
+ - (config->m_n_sub_partition_per_memory_channel - 1);
+ if(config->seperate_write_queue_enabled )
+ m_shared_credit_limit += config->gpgpu_frfcfs_dram_write_queue_size;
+ if (config->gpgpu_frfcfs_dram_sched_queue_size == 0
+ or config->gpgpu_dram_return_queue_size == 0)
+ {
+ m_shared_credit_limit = 0; // no limit if either of the queue has no limit in size
+ }
+ assert(m_shared_credit_limit >= 0);
}
-bool memory_partition_unit::arbitration_metadata::has_credits(
- int inner_sub_partition_id) const {
- int spid = inner_sub_partition_id;
- if (m_private_credit[spid] < m_private_credit_limit) {
- return true;
- } else if (m_shared_credit_limit == 0 ||
- m_shared_credit < m_shared_credit_limit) {
- return true;
- } else {
- return false;
- }
+bool memory_partition_unit::arbitration_metadata::has_credits(int inner_sub_partition_id) const
+{
+ int spid = inner_sub_partition_id;
+ if (m_private_credit[spid] < m_private_credit_limit) {
+ return true;
+ } else if (m_shared_credit_limit == 0 || m_shared_credit < m_shared_credit_limit) {
+ return true;
+ } else {
+ return false;
+ }
}
-void memory_partition_unit::arbitration_metadata::borrow_credit(
- int inner_sub_partition_id) {
- int spid = inner_sub_partition_id;
- if (m_private_credit[spid] < m_private_credit_limit) {
- m_private_credit[spid] += 1;
- } else if (m_shared_credit_limit == 0 ||
- m_shared_credit < m_shared_credit_limit) {
- m_shared_credit += 1;
- } else {
- assert(0 && "DRAM arbitration error: Borrowing from depleted credit!");
- }
- m_last_borrower = spid;
+void memory_partition_unit::arbitration_metadata::borrow_credit(int inner_sub_partition_id)
+{
+ int spid = inner_sub_partition_id;
+ if (m_private_credit[spid] < m_private_credit_limit) {
+ m_private_credit[spid] += 1;
+ } else if (m_shared_credit_limit == 0 || m_shared_credit < m_shared_credit_limit) {
+ m_shared_credit += 1;
+ } else {
+ assert(0 && "DRAM arbitration error: Borrowing from depleted credit!");
+ }
+ m_last_borrower = spid;
}
-void memory_partition_unit::arbitration_metadata::return_credit(
- int inner_sub_partition_id) {
- int spid = inner_sub_partition_id;
- if (m_private_credit[spid] > 0) {
- m_private_credit[spid] -= 1;
- } else {
- m_shared_credit -= 1;
- }
- assert((m_shared_credit >= 0) &&
- "DRAM arbitration error: Returning more than available credits!");
+void memory_partition_unit::arbitration_metadata::return_credit(int inner_sub_partition_id)
+{
+ int spid = inner_sub_partition_id;
+ if (m_private_credit[spid] > 0) {
+ m_private_credit[spid] -= 1;
+ } else {
+ m_shared_credit -= 1;
+ }
+ assert((m_shared_credit >= 0) && "DRAM arbitration error: Returning more than available credits!");
}
-void memory_partition_unit::arbitration_metadata::print(FILE *fp) const {
- fprintf(fp, "private_credit = ");
- for (unsigned p = 0; p < m_private_credit.size(); p++) {
- fprintf(fp, "%d ", m_private_credit[p]);
- }
- fprintf(fp, "(limit = %d)\n", m_private_credit_limit);
- fprintf(fp, "shared_credit = %d (limit = %d)\n", m_shared_credit,
- m_shared_credit_limit);
+void memory_partition_unit::arbitration_metadata::print( FILE *fp ) const
+{
+ fprintf(fp, "private_credit = ");
+ for (unsigned p = 0; p < m_private_credit.size(); p++) {
+ fprintf(fp, "%d ", m_private_credit[p]);
+ }
+ fprintf(fp, "(limit = %d)\n", m_private_credit_limit);
+ fprintf(fp, "shared_credit = %d (limit = %d)\n", m_shared_credit, m_shared_credit_limit);
}
-bool memory_partition_unit::busy() const {
- bool busy = false;
- for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel;
- p++) {
- if (m_sub_partition[p]->busy()) {
- busy = true;
+bool memory_partition_unit::busy() const
+{
+ bool busy = false;
+ for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel; p++) {
+ if (m_sub_partition[p]->busy()) {
+ busy = true;
+ }
}
- }
- return busy;
+ return busy;
}
-void memory_partition_unit::cache_cycle(unsigned cycle) {
- for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel;
- p++) {
- m_sub_partition[p]->cache_cycle(cycle);
- }
+void memory_partition_unit::cache_cycle(unsigned cycle)
+{
+ for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel; p++) {
+ m_sub_partition[p]->cache_cycle(cycle);
+ }
}
-void memory_partition_unit::visualizer_print(gzFile visualizer_file) const {
- m_dram->visualizer_print(visualizer_file);
- for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel;
- p++) {
- m_sub_partition[p]->visualizer_print(visualizer_file);
- }
+void memory_partition_unit::visualizer_print( gzFile visualizer_file ) const
+{
+ m_dram->visualizer_print(visualizer_file);
+ for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel; p++) {
+ m_sub_partition[p]->visualizer_print(visualizer_file);
+ }
}
-// determine whether a given subpartition can issue to DRAM
-bool memory_partition_unit::can_issue_to_dram(int inner_sub_partition_id) {
- int spid = inner_sub_partition_id;
- bool sub_partition_contention = m_sub_partition[spid]->dram_L2_queue_full();
- bool has_dram_resource = m_arbitration_metadata.has_credits(spid);
+// determine whether a given subpartition can issue to DRAM
+bool memory_partition_unit::can_issue_to_dram(int inner_sub_partition_id)
+{
+ int spid = inner_sub_partition_id;
+ bool sub_partition_contention = m_sub_partition[spid]->dram_L2_queue_full();
+ bool has_dram_resource = m_arbitration_metadata.has_credits(spid);
- MEMPART_DPRINTF(
- "sub partition %d sub_partition_contention=%c has_dram_resource=%c\n",
- spid, (sub_partition_contention) ? 'T' : 'F',
- (has_dram_resource) ? 'T' : 'F');
+ MEMPART_DPRINTF("sub partition %d sub_partition_contention=%c has_dram_resource=%c\n",
+ spid, (sub_partition_contention)? 'T':'F', (has_dram_resource)? 'T':'F');
- return (has_dram_resource && !sub_partition_contention);
+ return (has_dram_resource && !sub_partition_contention);
}
-int memory_partition_unit::global_sub_partition_id_to_local_id(
- int global_sub_partition_id) const {
- return (global_sub_partition_id -
- m_id * m_config->m_n_sub_partition_per_memory_channel);
+int memory_partition_unit::global_sub_partition_id_to_local_id(int global_sub_partition_id) const
+{
+ return (global_sub_partition_id - m_id * m_config->m_n_sub_partition_per_memory_channel);
}
-void memory_partition_unit::simple_dram_model_cycle() {
- // pop completed memory request from dram and push it to dram-to-L2 queue
- // of the original sub partition
- if (!m_dram_latency_queue.empty() &&
- ((m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle) >=
- m_dram_latency_queue.front().ready_cycle)) {
- mem_fetch *mf_return = m_dram_latency_queue.front().req;
- if (mf_return->get_access_type() != L1_WRBK_ACC &&
- mf_return->get_access_type() != L2_WRBK_ACC) {
- mf_return->set_reply();
+void memory_partition_unit::simple_dram_model_cycle()
+{
- unsigned dest_global_spid = mf_return->get_sub_partition_id();
- int dest_spid = global_sub_partition_id_to_local_id(dest_global_spid);
- assert(m_sub_partition[dest_spid]->get_id() == dest_global_spid);
- if (!m_sub_partition[dest_spid]->dram_L2_queue_full()) {
- if (mf_return->get_access_type() == L1_WRBK_ACC) {
- m_sub_partition[dest_spid]->set_done(mf_return);
- delete mf_return;
- } else {
- m_sub_partition[dest_spid]->dram_L2_queue_push(mf_return);
- mf_return->set_status(
- IN_PARTITION_DRAM_TO_L2_QUEUE,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- m_arbitration_metadata.return_credit(dest_spid);
- MEMPART_DPRINTF(
- "mem_fetch request %p return from dram to sub partition %d\n",
- mf_return, dest_spid);
- }
- m_dram_latency_queue.pop_front();
- }
+ // pop completed memory request from dram and push it to dram-to-L2 queue
+ // of the original sub partition
+ if (!m_dram_latency_queue.empty() && ( (m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle) >= m_dram_latency_queue.front().ready_cycle )) {
+ mem_fetch* mf_return = m_dram_latency_queue.front().req;
+ if( mf_return->get_access_type() != L1_WRBK_ACC && mf_return->get_access_type() != L2_WRBK_ACC ) {
+ mf_return->set_reply();
- } else {
- this->set_done(mf_return);
- delete mf_return;
- m_dram_latency_queue.pop_front();
- }
- }
+ unsigned dest_global_spid = mf_return->get_sub_partition_id();
+ int dest_spid = global_sub_partition_id_to_local_id(dest_global_spid);
+ assert(m_sub_partition[dest_spid]->get_id() == dest_global_spid);
+ if (!m_sub_partition[dest_spid]->dram_L2_queue_full()) {
+ if( mf_return->get_access_type() == L1_WRBK_ACC ) {
+ m_sub_partition[dest_spid]->set_done(mf_return);
+ delete mf_return;
+ } else {
+ m_sub_partition[dest_spid]->dram_L2_queue_push(mf_return);
+ mf_return->set_status(IN_PARTITION_DRAM_TO_L2_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_arbitration_metadata.return_credit(dest_spid);
+ MEMPART_DPRINTF("mem_fetch request %p return from dram to sub partition %d\n", mf_return, dest_spid);
+ }
+ m_dram_latency_queue.pop_front();
+ }
- // mem_fetch *mf = m_sub_partition[spid]->L2_dram_queue_top();
- // if( !m_dram->full(mf->is_write()) ) {
- // L2->DRAM queue to DRAM latency queue
- // Arbitrate among multiple L2 subpartitions
- int last_issued_partition = m_arbitration_metadata.last_borrower();
- for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel;
- p++) {
- int spid = (p + last_issued_partition + 1) %
- m_config->m_n_sub_partition_per_memory_channel;
- if (!m_sub_partition[spid]->L2_dram_queue_empty() &&
- can_issue_to_dram(spid)) {
- mem_fetch *mf = m_sub_partition[spid]->L2_dram_queue_top();
- if (m_dram->full(mf->is_write())) break;
+ } else {
+ this->set_done(mf_return);
+ delete mf_return;
+ m_dram_latency_queue.pop_front();
+ }
+ }
+
+ // mem_fetch *mf = m_sub_partition[spid]->L2_dram_queue_top();
+ //if( !m_dram->full(mf->is_write()) ) {
+ // L2->DRAM queue to DRAM latency queue
+ // Arbitrate among multiple L2 subpartitions
+ int last_issued_partition = m_arbitration_metadata.last_borrower();
+ for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel; p++) {
+ int spid = (p + last_issued_partition + 1) % m_config->m_n_sub_partition_per_memory_channel;
+ if (!m_sub_partition[spid]->L2_dram_queue_empty() && can_issue_to_dram(spid)) {
+ mem_fetch *mf = m_sub_partition[spid]->L2_dram_queue_top();
+ if(m_dram->full(mf->is_write()) )
+ break;
+
+ m_sub_partition[spid]->L2_dram_queue_pop();
+ MEMPART_DPRINTF("Issue mem_fetch request %p from sub partition %d to dram\n", mf, spid);
+ dram_delay_t d;
+ d.req = mf;
+ d.ready_cycle = m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle + m_config->dram_latency;
+ m_dram_latency_queue.push_back(d);
+ mf->set_status(IN_PARTITION_DRAM_LATENCY_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_arbitration_metadata.borrow_credit(spid);
+ break; // the DRAM should only accept one request per cycle
+ }
+ }
+ //}
- m_sub_partition[spid]->L2_dram_queue_pop();
- MEMPART_DPRINTF(
- "Issue mem_fetch request %p from sub partition %d to dram\n", mf,
- spid);
- dram_delay_t d;
- d.req = mf;
- d.ready_cycle = m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle +
- m_config->dram_latency;
- m_dram_latency_queue.push_back(d);
- mf->set_status(IN_PARTITION_DRAM_LATENCY_QUEUE,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- m_arbitration_metadata.borrow_credit(spid);
- break; // the DRAM should only accept one request per cycle
- }
- }
- //}
}
-void memory_partition_unit::dram_cycle() {
- // pop completed memory request from dram and push it to dram-to-L2 queue
- // of the original sub partition
- mem_fetch *mf_return = m_dram->return_queue_top();
- if (mf_return) {
- unsigned dest_global_spid = mf_return->get_sub_partition_id();
- int dest_spid = global_sub_partition_id_to_local_id(dest_global_spid);
- assert(m_sub_partition[dest_spid]->get_id() == dest_global_spid);
- if (!m_sub_partition[dest_spid]->dram_L2_queue_full()) {
- if (mf_return->get_access_type() == L1_WRBK_ACC) {
- m_sub_partition[dest_spid]->set_done(mf_return);
- delete mf_return;
- } else {
- m_sub_partition[dest_spid]->dram_L2_queue_push(mf_return);
- mf_return->set_status(IN_PARTITION_DRAM_TO_L2_QUEUE,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- m_arbitration_metadata.return_credit(dest_spid);
- MEMPART_DPRINTF(
- "mem_fetch request %p return from dram to sub partition %d\n",
- mf_return, dest_spid);
- }
- m_dram->return_queue_pop();
+void memory_partition_unit::dram_cycle()
+{
+ // pop completed memory request from dram and push it to dram-to-L2 queue
+ // of the original sub partition
+ mem_fetch* mf_return = m_dram->return_queue_top();
+ if (mf_return) {
+ unsigned dest_global_spid = mf_return->get_sub_partition_id();
+ int dest_spid = global_sub_partition_id_to_local_id(dest_global_spid);
+ assert(m_sub_partition[dest_spid]->get_id() == dest_global_spid);
+ if (!m_sub_partition[dest_spid]->dram_L2_queue_full()) {
+ if( mf_return->get_access_type() == L1_WRBK_ACC ) {
+ m_sub_partition[dest_spid]->set_done(mf_return);
+ delete mf_return;
+ } else {
+ m_sub_partition[dest_spid]->dram_L2_queue_push(mf_return);
+ mf_return->set_status(IN_PARTITION_DRAM_TO_L2_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_arbitration_metadata.return_credit(dest_spid);
+ MEMPART_DPRINTF("mem_fetch request %p return from dram to sub partition %d\n", mf_return, dest_spid);
+ }
+ m_dram->return_queue_pop();
+ }
+ } else {
+ m_dram->return_queue_pop();
}
- } else {
- m_dram->return_queue_pop();
- }
+
+ m_dram->cycle();
+ m_dram->dram_log(SAMPLELOG);
- m_dram->cycle();
- m_dram->dram_log(SAMPLELOG);
+ // mem_fetch *mf = m_sub_partition[spid]->L2_dram_queue_top();
+ //if( !m_dram->full(mf->is_write()) ) {
+ // L2->DRAM queue to DRAM latency queue
+ // Arbitrate among multiple L2 subpartitions
+ int last_issued_partition = m_arbitration_metadata.last_borrower();
+ for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel; p++) {
+ int spid = (p + last_issued_partition + 1) % m_config->m_n_sub_partition_per_memory_channel;
+ if (!m_sub_partition[spid]->L2_dram_queue_empty() && can_issue_to_dram(spid)) {
+ mem_fetch *mf = m_sub_partition[spid]->L2_dram_queue_top();
+ if(m_dram->full(mf->is_write()) )
+ break;
- // mem_fetch *mf = m_sub_partition[spid]->L2_dram_queue_top();
- // if( !m_dram->full(mf->is_write()) ) {
- // L2->DRAM queue to DRAM latency queue
- // Arbitrate among multiple L2 subpartitions
- int last_issued_partition = m_arbitration_metadata.last_borrower();
- for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel;
- p++) {
- int spid = (p + last_issued_partition + 1) %
- m_config->m_n_sub_partition_per_memory_channel;
- if (!m_sub_partition[spid]->L2_dram_queue_empty() &&
- can_issue_to_dram(spid)) {
- mem_fetch *mf = m_sub_partition[spid]->L2_dram_queue_top();
- if (m_dram->full(mf->is_write())) break;
+ m_sub_partition[spid]->L2_dram_queue_pop();
+ MEMPART_DPRINTF("Issue mem_fetch request %p from sub partition %d to dram\n", mf, spid);
+ dram_delay_t d;
+ d.req = mf;
+ d.ready_cycle = m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle + m_config->dram_latency;
+ m_dram_latency_queue.push_back(d);
+ mf->set_status(IN_PARTITION_DRAM_LATENCY_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_arbitration_metadata.borrow_credit(spid);
+ break; // the DRAM should only accept one request per cycle
+ }
+ }
+ //}
- m_sub_partition[spid]->L2_dram_queue_pop();
- MEMPART_DPRINTF(
- "Issue mem_fetch request %p from sub partition %d to dram\n", mf,
- spid);
- dram_delay_t d;
- d.req = mf;
- d.ready_cycle = m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle +
- m_config->dram_latency;
- m_dram_latency_queue.push_back(d);
- mf->set_status(IN_PARTITION_DRAM_LATENCY_QUEUE,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- m_arbitration_metadata.borrow_credit(spid);
- break; // the DRAM should only accept one request per cycle
+ // DRAM latency queue
+ if( !m_dram_latency_queue.empty() && ( (m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle) >= m_dram_latency_queue.front().ready_cycle ) && !m_dram->full(m_dram_latency_queue.front().req->is_write()) ) {
+ mem_fetch* mf = m_dram_latency_queue.front().req;
+ m_dram_latency_queue.pop_front();
+ m_dram->push(mf);
}
- }
- //}
-
- // DRAM latency queue
- if (!m_dram_latency_queue.empty() &&
- ((m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle) >=
- m_dram_latency_queue.front().ready_cycle) &&
- !m_dram->full(m_dram_latency_queue.front().req->is_write())) {
- mem_fetch *mf = m_dram_latency_queue.front().req;
- m_dram_latency_queue.pop_front();
- m_dram->push(mf);
- }
}
-void memory_partition_unit::set_done(mem_fetch *mf) {
- unsigned global_spid = mf->get_sub_partition_id();
- int spid = global_sub_partition_id_to_local_id(global_spid);
- assert(m_sub_partition[spid]->get_id() == global_spid);
- if (mf->get_access_type() == L1_WRBK_ACC ||
- mf->get_access_type() == L2_WRBK_ACC) {
- m_arbitration_metadata.return_credit(spid);
- MEMPART_DPRINTF(
- "mem_fetch request %p return from dram to sub partition %d\n", mf,
- spid);
- }
- m_sub_partition[spid]->set_done(mf);
+void memory_partition_unit::set_done( mem_fetch *mf )
+{
+ unsigned global_spid = mf->get_sub_partition_id();
+ int spid = global_sub_partition_id_to_local_id(global_spid);
+ assert(m_sub_partition[spid]->get_id() == global_spid);
+ if (mf->get_access_type() == L1_WRBK_ACC || mf->get_access_type() == L2_WRBK_ACC) {
+ m_arbitration_metadata.return_credit(spid);
+ MEMPART_DPRINTF("mem_fetch request %p return from dram to sub partition %d\n", mf, spid);
+ }
+ m_sub_partition[spid]->set_done(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_req) const {
- m_dram->set_dram_power_stats(n_cmd, n_activity, n_nop, n_act, n_pre, n_rd,
- n_wr, n_req);
+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_req) const
+{
+ m_dram->set_dram_power_stats(n_cmd, n_activity, n_nop, n_act, n_pre, n_rd, n_wr, n_req);
}
-void memory_partition_unit::print(FILE *fp) const {
- fprintf(fp, "Memory Partition %u: \n", m_id);
- for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel;
- p++) {
- m_sub_partition[p]->print(fp);
- }
- fprintf(fp, "In Dram Latency Queue (total = %zd): \n",
- m_dram_latency_queue.size());
- for (std::list<dram_delay_t>::const_iterator mf_dlq =
- m_dram_latency_queue.begin();
- mf_dlq != m_dram_latency_queue.end(); ++mf_dlq) {
- mem_fetch *mf = mf_dlq->req;
- fprintf(fp, "Ready @ %llu - ", mf_dlq->ready_cycle);
- if (mf)
- mf->print(fp);
- else
- fprintf(fp, " <NULL mem_fetch?>\n");
- }
- m_dram->print(fp);
+void memory_partition_unit::print( FILE *fp ) const
+{
+ fprintf(fp, "Memory Partition %u: \n", m_id);
+ for (unsigned p = 0; p < m_config->m_n_sub_partition_per_memory_channel; p++) {
+ m_sub_partition[p]->print(fp);
+ }
+ fprintf(fp, "In Dram Latency Queue (total = %zd): \n", m_dram_latency_queue.size());
+ for (std::list<dram_delay_t>::const_iterator mf_dlq = m_dram_latency_queue.begin();
+ mf_dlq != m_dram_latency_queue.end(); ++mf_dlq) {
+ mem_fetch *mf = mf_dlq->req;
+ fprintf(fp, "Ready @ %llu - ", mf_dlq->ready_cycle);
+ if (mf)
+ mf->print(fp);
+ else
+ fprintf(fp, " <NULL mem_fetch?>\n");
+ }
+ m_dram->print(fp);
}
-memory_sub_partition::memory_sub_partition(unsigned sub_partition_id,
- const memory_config *config,
- class memory_stats_t *stats,
- class gpgpu_sim *gpu) {
- m_id = sub_partition_id;
- m_config = config;
- m_stats = stats;
- m_gpu = gpu;
- m_memcpy_cycle_offset = 0;
+memory_sub_partition::memory_sub_partition( unsigned sub_partition_id,
+ const memory_config *config,
+ class memory_stats_t *stats,
+ class gpgpu_sim* gpu)
+{
+ m_id = sub_partition_id;
+ m_config=config;
+ m_stats=stats;
+ m_gpu = gpu;
+ m_memcpy_cycle_offset = 0;
- assert(m_id < m_config->m_n_mem_sub_partition);
+ assert(m_id < m_config->m_n_mem_sub_partition);
- char L2c_name[32];
- snprintf(L2c_name, 32, "L2_bank_%03d", m_id);
- m_L2interface = new L2interface(this);
- m_mf_allocator = new partition_mf_allocator(config);
+ char L2c_name[32];
+ snprintf(L2c_name, 32, "L2_bank_%03d", m_id);
+ m_L2interface = new L2interface(this);
+ 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);
+ 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);
- unsigned int icnt_L2;
- unsigned int L2_dram;
- unsigned int dram_L2;
- unsigned int L2_icnt;
- sscanf(m_config->gpgpu_L2_queue_config, "%u:%u:%u:%u", &icnt_L2, &L2_dram,
- &dram_L2, &L2_icnt);
- m_icnt_L2_queue = new fifo_pipeline<mem_fetch>("icnt-to-L2", 0, icnt_L2);
- m_L2_dram_queue = new fifo_pipeline<mem_fetch>("L2-to-dram", 0, L2_dram);
- m_dram_L2_queue = new fifo_pipeline<mem_fetch>("dram-to-L2", 0, dram_L2);
- m_L2_icnt_queue = new fifo_pipeline<mem_fetch>("L2-to-icnt", 0, L2_icnt);
- wb_addr = -1;
+ unsigned int icnt_L2;
+ unsigned int L2_dram;
+ unsigned int dram_L2;
+ unsigned int L2_icnt;
+ sscanf(m_config->gpgpu_L2_queue_config,"%u:%u:%u:%u", &icnt_L2,&L2_dram,&dram_L2,&L2_icnt );
+ m_icnt_L2_queue = new fifo_pipeline<mem_fetch>("icnt-to-L2",0,icnt_L2);
+ m_L2_dram_queue = new fifo_pipeline<mem_fetch>("L2-to-dram",0,L2_dram);
+ m_dram_L2_queue = new fifo_pipeline<mem_fetch>("dram-to-L2",0,dram_L2);
+ m_L2_icnt_queue = new fifo_pipeline<mem_fetch>("L2-to-icnt",0,L2_icnt);
+ wb_addr=-1;
}
-memory_sub_partition::~memory_sub_partition() {
- delete m_icnt_L2_queue;
- delete m_L2_dram_queue;
- delete m_dram_L2_queue;
- delete m_L2_icnt_queue;
- delete m_L2cache;
- delete m_L2interface;
+memory_sub_partition::~memory_sub_partition()
+{
+ delete m_icnt_L2_queue;
+ delete m_L2_dram_queue;
+ delete m_dram_L2_queue;
+ delete m_L2_icnt_queue;
+ delete m_L2cache;
+ delete m_L2interface;
}
-void memory_sub_partition::cache_cycle(unsigned cycle) {
- // L2 fill responses
- if (!m_config->m_L2_config.disabled()) {
- if (m_L2cache->access_ready() && !m_L2_icnt_queue->full()) {
- mem_fetch *mf = m_L2cache->next_access();
- if (mf->get_access_type() !=
- L2_WR_ALLOC_R) { // Don't pass write allocate read request back to
- // upper level cache
- mf->set_reply();
- mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- m_L2_icnt_queue->push(mf);
- } else {
- if (m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE) {
- mem_fetch *original_wr_mf = mf->get_original_wr_mf();
- assert(original_wr_mf);
- original_wr_mf->set_reply();
- original_wr_mf->set_status(
- IN_PARTITION_L2_TO_ICNT_QUEUE,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- m_L2_icnt_queue->push(original_wr_mf);
- }
- m_request_tracker.erase(mf);
- delete mf;
- }
+void memory_sub_partition::cache_cycle( unsigned cycle )
+{
+ // L2 fill responses
+ if( !m_config->m_L2_config.disabled()) {
+ if ( m_L2cache->access_ready() && !m_L2_icnt_queue->full() ) {
+ mem_fetch *mf = m_L2cache->next_access();
+ if(mf->get_access_type() != L2_WR_ALLOC_R){ // Don't pass write allocate read request back to upper level cache
+ mf->set_reply();
+ mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_L2_icnt_queue->push(mf);
+ }else{
+ if(m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE)
+ {
+ mem_fetch* original_wr_mf = mf->get_original_wr_mf();
+ assert(original_wr_mf);
+ original_wr_mf->set_reply();
+ original_wr_mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_L2_icnt_queue->push(original_wr_mf);
+ }
+ m_request_tracker.erase(mf);
+ delete mf;
+ }
+ }
}
- }
- // DRAM to L2 (texture) and icnt (not texture)
- if (!m_dram_L2_queue->empty()) {
- mem_fetch *mf = m_dram_L2_queue->top();
- if (!m_config->m_L2_config.disabled() && m_L2cache->waiting_for_fill(mf)) {
- if (m_L2cache->fill_port_free()) {
- mf->set_status(IN_PARTITION_L2_FILL_QUEUE,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- m_L2cache->fill(mf, m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle +
- m_memcpy_cycle_offset);
- m_dram_L2_queue->pop();
- }
- } else if (!m_L2_icnt_queue->full()) {
- if (mf->is_write() && mf->get_type() == WRITE_ACK)
- mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- m_L2_icnt_queue->push(mf);
- m_dram_L2_queue->pop();
+ // DRAM to L2 (texture) and icnt (not texture)
+ if ( !m_dram_L2_queue->empty() ) {
+ mem_fetch *mf = m_dram_L2_queue->top();
+ if ( !m_config->m_L2_config.disabled() && m_L2cache->waiting_for_fill(mf) ) {
+ if (m_L2cache->fill_port_free()) {
+ mf->set_status(IN_PARTITION_L2_FILL_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_L2cache->fill(mf,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle+m_memcpy_cycle_offset);
+ m_dram_L2_queue->pop();
+ }
+ } else if ( !m_L2_icnt_queue->full() ) {
+ if(mf->is_write() && mf->get_type() == WRITE_ACK)
+ mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_L2_icnt_queue->push(mf);
+ m_dram_L2_queue->pop();
+ }
}
- }
- // prior L2 misses inserted into m_L2_dram_queue here
- if (!m_config->m_L2_config.disabled()) m_L2cache->cycle();
+ // prior L2 misses inserted into m_L2_dram_queue here
+ if( !m_config->m_L2_config.disabled() )
+ m_L2cache->cycle();
- // new L2 texture accesses and/or non-texture accesses
- if (!m_L2_dram_queue->full() && !m_icnt_L2_queue->empty()) {
- mem_fetch *mf = m_icnt_L2_queue->top();
- if (!m_config->m_L2_config.disabled() &&
- ((m_config->m_L2_texure_only && mf->istexture()) ||
- (!m_config->m_L2_texure_only))) {
- // L2 is enabled and access is for L2
- bool output_full = m_L2_icnt_queue->full();
- bool port_free = m_L2cache->data_port_free();
- if (!output_full && port_free) {
- std::list<cache_event> events;
- enum cache_request_status status =
- m_L2cache->access(mf->get_addr(), mf,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle +
- m_memcpy_cycle_offset,
- events);
- bool write_sent = was_write_sent(events);
- bool read_sent = was_read_sent(events);
- MEM_SUBPART_DPRINTF("Probing L2 cache Address=%llx, status=%u\n",
- mf->get_addr(), status);
+ // new L2 texture accesses and/or non-texture accesses
+ if ( !m_L2_dram_queue->full() && !m_icnt_L2_queue->empty() ) {
+ mem_fetch *mf = m_icnt_L2_queue->top();
+ if ( !m_config->m_L2_config.disabled() &&
+ ( (m_config->m_L2_texure_only && mf->istexture()) || (!m_config->m_L2_texure_only) )
+ ) {
+ // L2 is enabled and access is for L2
+ bool output_full = m_L2_icnt_queue->full();
+ bool port_free = m_L2cache->data_port_free();
+ if ( !output_full && port_free ) {
+ std::list<cache_event> events;
+ enum cache_request_status status = m_L2cache->access(mf->get_addr(),mf,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle+m_memcpy_cycle_offset,events);
+ bool write_sent = was_write_sent(events);
+ bool read_sent = was_read_sent(events);
+ MEM_SUBPART_DPRINTF("Probing L2 cache Address=%llx, status=%u\n", mf->get_addr(), status);
- if (status == HIT) {
- if (!write_sent) {
- // L2 cache replies
- assert(!read_sent);
- if (mf->get_access_type() == L1_WRBK_ACC) {
- m_request_tracker.erase(mf);
- delete mf;
- } else {
- mf->set_reply();
- mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- m_L2_icnt_queue->push(mf);
+ if ( status == HIT ) {
+ if( !write_sent ) {
+ // L2 cache replies
+ assert(!read_sent);
+ if( mf->get_access_type() == L1_WRBK_ACC ) {
+ m_request_tracker.erase(mf);
+ delete mf;
+ } else {
+ mf->set_reply();
+ mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_L2_icnt_queue->push(mf);
+ }
+ m_icnt_L2_queue->pop();
+ } else {
+ assert(write_sent);
+ m_icnt_L2_queue->pop();
+ }
+ } else if ( status != RESERVATION_FAIL ) {
+ if(mf->is_write() && (m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE || m_config->m_L2_config.m_write_alloc_policy == LAZY_FETCH_ON_READ) && !was_writeallocate_sent(events)) {
+ mf->set_reply();
+ mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_L2_icnt_queue->push(mf);
+ }
+ // L2 cache accepted request
+ m_icnt_L2_queue->pop();
+ } else {
+ assert(!write_sent);
+ assert(!read_sent);
+ // L2 cache lock-up: will try again next cycle
+ }
}
- m_icnt_L2_queue->pop();
- } else {
- assert(write_sent);
- m_icnt_L2_queue->pop();
- }
- } else if (status != RESERVATION_FAIL) {
- if (mf->is_write() &&
- (m_config->m_L2_config.m_write_alloc_policy == FETCH_ON_WRITE ||
- m_config->m_L2_config.m_write_alloc_policy ==
- LAZY_FETCH_ON_READ) &&
- !was_writeallocate_sent(events)) {
- mf->set_reply();
- mf->set_status(IN_PARTITION_L2_TO_ICNT_QUEUE,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- m_L2_icnt_queue->push(mf);
- }
- // L2 cache accepted request
- m_icnt_L2_queue->pop();
} else {
- assert(!write_sent);
- assert(!read_sent);
- // L2 cache lock-up: will try again next cycle
+ // L2 is disabled or non-texture access to texture-only L2
+ mf->set_status(IN_PARTITION_L2_TO_DRAM_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ m_L2_dram_queue->push(mf);
+ m_icnt_L2_queue->pop();
}
- }
- } else {
- // L2 is disabled or non-texture access to texture-only L2
- mf->set_status(IN_PARTITION_L2_TO_DRAM_QUEUE,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- m_L2_dram_queue->push(mf);
- m_icnt_L2_queue->pop();
}
- }
- // ROP delay queue
- if (!m_rop.empty() && (cycle >= m_rop.front().ready_cycle) &&
- !m_icnt_L2_queue->full()) {
- mem_fetch *mf = m_rop.front().req;
- m_rop.pop();
- m_icnt_L2_queue->push(mf);
- mf->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- }
+ // ROP delay queue
+ if( !m_rop.empty() && (cycle >= m_rop.front().ready_cycle) && !m_icnt_L2_queue->full() ) {
+ mem_fetch* mf = m_rop.front().req;
+ m_rop.pop();
+ m_icnt_L2_queue->push(mf);
+ mf->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ }
}
-bool memory_sub_partition::full() const { return m_icnt_L2_queue->full(); }
+bool memory_sub_partition::full() const
+{
+ return m_icnt_L2_queue->full();
+}
-bool memory_sub_partition::full(unsigned size) const {
- return m_icnt_L2_queue->is_avilable_size(size);
+bool memory_sub_partition::full(unsigned size) const
+{
+ return m_icnt_L2_queue->is_avilable_size(size);
}
-bool memory_sub_partition::L2_dram_queue_empty() const {
- return m_L2_dram_queue->empty();
+bool memory_sub_partition::L2_dram_queue_empty() const
+{
+ return m_L2_dram_queue->empty();
}
-class mem_fetch *memory_sub_partition::L2_dram_queue_top() const {
- return m_L2_dram_queue->top();
+class mem_fetch* memory_sub_partition::L2_dram_queue_top() const
+{
+ return m_L2_dram_queue->top();
}
-void memory_sub_partition::L2_dram_queue_pop() { m_L2_dram_queue->pop(); }
+void memory_sub_partition::L2_dram_queue_pop()
+{
+ m_L2_dram_queue->pop();
+}
-bool memory_sub_partition::dram_L2_queue_full() const {
- return m_dram_L2_queue->full();
+bool memory_sub_partition::dram_L2_queue_full() const
+{
+ return m_dram_L2_queue->full();
}
-void memory_sub_partition::dram_L2_queue_push(class mem_fetch *mf) {
- m_dram_L2_queue->push(mf);
+void memory_sub_partition::dram_L2_queue_push( class mem_fetch* mf )
+{
+ m_dram_L2_queue->push(mf);
}
-void memory_sub_partition::print_cache_stat(unsigned &accesses,
- unsigned &misses) const {
- FILE *fp = stdout;
- if (!m_config->m_L2_config.disabled()) m_L2cache->print(fp, accesses, misses);
+void memory_sub_partition::print_cache_stat(unsigned &accesses, unsigned &misses) const
+{
+ FILE *fp = stdout;
+ if( !m_config->m_L2_config.disabled() )
+ m_L2cache->print(fp,accesses,misses);
}
-void memory_sub_partition::print(FILE *fp) const {
- if (!m_request_tracker.empty()) {
- fprintf(fp, "Memory Sub Parition %u: pending memory requests:\n", m_id);
- for (std::set<mem_fetch *>::const_iterator r = m_request_tracker.begin();
- r != m_request_tracker.end(); ++r) {
- mem_fetch *mf = *r;
- if (mf)
- mf->print(fp);
- else
- fprintf(fp, " <NULL mem_fetch?>\n");
+void memory_sub_partition::print( FILE *fp ) const
+{
+ if ( !m_request_tracker.empty() ) {
+ fprintf(fp,"Memory Sub Parition %u: pending memory requests:\n", m_id);
+ for ( std::set<mem_fetch*>::const_iterator r=m_request_tracker.begin(); r != m_request_tracker.end(); ++r ) {
+ mem_fetch *mf = *r;
+ if ( mf )
+ mf->print(fp);
+ else
+ fprintf(fp," <NULL mem_fetch?>\n");
+ }
}
- }
- if (!m_config->m_L2_config.disabled()) m_L2cache->display_state(fp);
+ if( !m_config->m_L2_config.disabled() )
+ m_L2cache->display_state(fp);
}
-void memory_stats_t::visualizer_print(gzFile visualizer_file) {
- gzprintf(visualizer_file, "Ltwowritemiss: %d\n", L2_write_miss);
- gzprintf(visualizer_file, "Ltwowritehit: %d\n", L2_write_hit);
- gzprintf(visualizer_file, "Ltworeadmiss: %d\n", L2_read_miss);
- gzprintf(visualizer_file, "Ltworeadhit: %d\n", L2_read_hit);
- clear_L2_stats_pw();
+void memory_stats_t::visualizer_print( gzFile visualizer_file )
+{
+ gzprintf(visualizer_file, "Ltwowritemiss: %d\n", L2_write_miss);
+ gzprintf(visualizer_file, "Ltwowritehit: %d\n", L2_write_hit);
+ gzprintf(visualizer_file, "Ltworeadmiss: %d\n", L2_read_miss);
+ gzprintf(visualizer_file, "Ltworeadhit: %d\n", L2_read_hit);
+ clear_L2_stats_pw();
- if (num_mfs)
- gzprintf(visualizer_file, "averagemflatency: %lld\n",
- mf_total_lat / num_mfs);
+ if (num_mfs)
+ gzprintf(visualizer_file, "averagemflatency: %lld\n", mf_total_lat/num_mfs);
}
-void memory_stats_t::clear_L2_stats_pw() {
- L2_write_miss = 0;
- L2_write_hit = 0;
- L2_read_miss = 0;
- L2_read_hit = 0;
+void memory_stats_t::clear_L2_stats_pw(){
+ L2_write_miss = 0;
+ L2_write_hit = 0;
+ L2_read_miss = 0;
+ L2_read_hit = 0;
}
-void gpgpu_sim::print_dram_stats(FILE *fout) const {
- unsigned cmd = 0;
- unsigned activity = 0;
- unsigned nop = 0;
- unsigned act = 0;
- unsigned pre = 0;
- unsigned rd = 0;
- unsigned wr = 0;
- unsigned req = 0;
- unsigned tot_cmd = 0;
- unsigned tot_nop = 0;
- unsigned tot_act = 0;
- unsigned tot_pre = 0;
- unsigned tot_rd = 0;
- unsigned tot_wr = 0;
- unsigned tot_req = 0;
+void gpgpu_sim::print_dram_stats(FILE *fout) const
+{
+ unsigned cmd=0;
+ unsigned activity=0;
+ unsigned nop=0;
+ unsigned act=0;
+ unsigned pre=0;
+ unsigned rd=0;
+ unsigned wr=0;
+ unsigned req=0;
+ unsigned tot_cmd=0;
+ unsigned tot_nop=0;
+ unsigned tot_act=0;
+ unsigned tot_pre=0;
+ unsigned tot_rd=0;
+ unsigned tot_wr=0;
+ unsigned tot_req=0;
- for (unsigned i = 0; i < m_memory_config->m_n_mem; i++) {
- m_memory_partition_unit[i]->set_dram_power_stats(cmd, activity, nop, act,
- pre, rd, wr, req);
- tot_cmd += cmd;
- tot_nop += nop;
- tot_act += act;
- tot_pre += pre;
- tot_rd += rd;
- tot_wr += wr;
- tot_req += req;
- }
- fprintf(fout, "gpgpu_n_dram_reads = %d\n", tot_rd);
- fprintf(fout, "gpgpu_n_dram_writes = %d\n", tot_wr);
- fprintf(fout, "gpgpu_n_dram_activate = %d\n", tot_act);
- fprintf(fout, "gpgpu_n_dram_commands = %d\n", tot_cmd);
- fprintf(fout, "gpgpu_n_dram_noops = %d\n", tot_nop);
- fprintf(fout, "gpgpu_n_dram_precharges = %d\n", tot_pre);
- fprintf(fout, "gpgpu_n_dram_requests = %d\n", tot_req);
+ for (unsigned i=0;i<m_memory_config->m_n_mem;i++){
+ m_memory_partition_unit[i]->set_dram_power_stats(cmd,activity,nop,act,pre,rd,wr,req);
+ tot_cmd+=cmd;
+ tot_nop+=nop;
+ tot_act+=act;
+ tot_pre+=pre;
+ tot_rd+=rd;
+ tot_wr+=wr;
+ tot_req+=req;
+ }
+ fprintf(fout,"gpgpu_n_dram_reads = %d\n",tot_rd );
+ fprintf(fout,"gpgpu_n_dram_writes = %d\n",tot_wr );
+ fprintf(fout,"gpgpu_n_dram_activate = %d\n",tot_act );
+ fprintf(fout,"gpgpu_n_dram_commands = %d\n",tot_cmd);
+ fprintf(fout,"gpgpu_n_dram_noops = %d\n",tot_nop );
+ fprintf(fout,"gpgpu_n_dram_precharges = %d\n",tot_pre );
+ fprintf(fout,"gpgpu_n_dram_requests = %d\n",tot_req );
+}
+
+unsigned memory_sub_partition::flushL2()
+{
+ if (!m_config->m_L2_config.disabled()) {
+ m_L2cache->flush();
+ }
+ return 0; //TODO: write the flushed data to the main memory
}
-unsigned memory_sub_partition::flushL2() {
- if (!m_config->m_L2_config.disabled()) {
- m_L2cache->flush();
- }
- return 0; // TODO: write the flushed data to the main memory
+unsigned memory_sub_partition::invalidateL2()
+{
+ if (!m_config->m_L2_config.disabled()) {
+ m_L2cache->invalidate();
+ }
+ return 0;
}
-unsigned memory_sub_partition::invalidateL2() {
- if (!m_config->m_L2_config.disabled()) {
- m_L2cache->invalidate();
- }
- return 0;
+bool memory_sub_partition::busy() const
+{
+ return !m_request_tracker.empty();
}
-bool memory_sub_partition::busy() const { return !m_request_tracker.empty(); }
+std::vector<mem_fetch*> memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch* mf)
+{
+ std::vector<mem_fetch*> result;
-std::vector<mem_fetch *>
-memory_sub_partition::breakdown_request_to_sector_requests(mem_fetch *mf) {
- std::vector<mem_fetch *> result;
+ if(mf->get_data_size() == SECTOR_SIZE && mf->get_access_sector_mask().count() == 1) {
+ result.push_back(mf);
+ } else if (mf->get_data_size() == 128 || mf->get_data_size() == 64) {
+ //We only accept 32, 64 and 128 bytes reqs
+ unsigned start=0, end=0;
+ if(mf->get_data_size() == 128) {
+ start=0; end=3;
+ } else if (mf->get_data_size() == 64 && mf->get_access_sector_mask().to_string() == "1100") {
+ start=2; end=3;
+ } else if (mf->get_data_size() == 64 && mf->get_access_sector_mask().to_string() == "0011") {
+ start=0; end=1;
+ } else if (mf->get_data_size() == 64 && (mf->get_access_sector_mask().to_string() == "1111" || mf->get_access_sector_mask().to_string() == "0000")) {
+ if(mf->get_addr() % 128 == 0) {
+ start=0; end=1;
+ } else {
+ start=2; end=3;
+ }
+ } else
+ {
+ printf("Invalid sector received, address = 0x%06llx, sector mask = %s, data size = %d",
+ mf->get_addr(), mf->get_access_sector_mask(), mf->get_data_size());
+ assert(0 && "Undefined sector mask is received");
+ }
- if (mf->get_data_size() == SECTOR_SIZE &&
- mf->get_access_sector_mask().count() == 1) {
- result.push_back(mf);
- } else if (mf->get_data_size() == 128 || mf->get_data_size() == 64) {
- // We only accept 32, 64 and 128 bytes reqs
- unsigned start = 0, end = 0;
- if (mf->get_data_size() == 128) {
- start = 0;
- end = 3;
- } else if (mf->get_data_size() == 64 &&
- mf->get_access_sector_mask().to_string() == "1100") {
- start = 2;
- end = 3;
- } else if (mf->get_data_size() == 64 &&
- mf->get_access_sector_mask().to_string() == "0011") {
- start = 0;
- end = 1;
- } else if (mf->get_data_size() == 64 &&
- (mf->get_access_sector_mask().to_string() == "1111" ||
- mf->get_access_sector_mask().to_string() == "0000")) {
- if (mf->get_addr() % 128 == 0) {
- start = 0;
- end = 1;
- } else {
- start = 2;
- end = 3;
- }
- } else {
- printf(
- "Invalid sector received, address = 0x%06llx, sector mask = %s, data "
- "size = %d",
- mf->get_addr(), mf->get_access_sector_mask(), mf->get_data_size());
- assert(0 && "Undefined sector mask is received");
- }
+ std::bitset<SECTOR_SIZE*SECTOR_CHUNCK_SIZE> byte_sector_mask;
+ byte_sector_mask.reset();
+ for(unsigned k=start*SECTOR_SIZE; k< SECTOR_SIZE; ++k)
+ byte_sector_mask.set(k);
- std::bitset<SECTOR_SIZE * SECTOR_CHUNCK_SIZE> byte_sector_mask;
- byte_sector_mask.reset();
- for (unsigned k = start * SECTOR_SIZE; k < SECTOR_SIZE; ++k)
- byte_sector_mask.set(k);
+ for(unsigned j=start, i=0; j<= end ; ++j, ++i){
- for (unsigned j = start, i = 0; j <= end; ++j, ++i) {
- const mem_access_t *ma = new mem_access_t(
- mf->get_access_type(), mf->get_addr() + SECTOR_SIZE * i, SECTOR_SIZE,
- mf->is_write(), mf->get_access_warp_mask(),
- mf->get_access_byte_mask() & byte_sector_mask,
- std::bitset<SECTOR_CHUNCK_SIZE>().set(j), m_gpu->gpgpu_ctx);
+ const mem_access_t *ma = new mem_access_t( mf->get_access_type(),
+ mf->get_addr() + SECTOR_SIZE*i,
+ SECTOR_SIZE,
+ mf->is_write(),
+ mf->get_access_warp_mask(),
+ mf->get_access_byte_mask() & byte_sector_mask,
+ std::bitset<SECTOR_CHUNCK_SIZE>().set(j),
+ 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, mf);
+ 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,
+ mf);
- result.push_back(n_mf);
- byte_sector_mask <<= SECTOR_SIZE;
- }
- } else {
- printf(
- "Invalid sector received, address = 0x%06llx, sector mask = %d, byte "
- "mask = , data size = %u",
- mf->get_addr(), mf->get_access_sector_mask().count(),
- mf->get_data_size());
- assert(0 && "Undefined data size is received");
- }
+ result.push_back(n_mf);
+ byte_sector_mask <<= SECTOR_SIZE;
+ }
+ } else {
+ printf("Invalid sector received, address = 0x%06llx, sector mask = %d, byte mask = , data size = %u",
+ mf->get_addr(), mf->get_access_sector_mask().count(), mf->get_data_size());
+ assert(0 && "Undefined data size is received");
+ }
- return result;
+ return result;
}
-void memory_sub_partition::push(mem_fetch *m_req, unsigned long long cycle) {
- if (m_req) {
- m_stats->memlatstat_icnt2mem_pop(m_req);
- std::vector<mem_fetch *> reqs;
- if (m_config->m_L2_config.m_cache_type == SECTOR)
- reqs = breakdown_request_to_sector_requests(m_req);
- else
- reqs.push_back(m_req);
+void memory_sub_partition::push( mem_fetch* m_req, unsigned long long cycle )
+{
+ if (m_req) {
+ m_stats->memlatstat_icnt2mem_pop(m_req);
+ std::vector<mem_fetch*> reqs;
+ if(m_config->m_L2_config.m_cache_type == SECTOR)
+ reqs = breakdown_request_to_sector_requests(m_req);
+ else
+ reqs.push_back(m_req);
- for (unsigned i = 0; i < reqs.size(); ++i) {
- mem_fetch *req = reqs[i];
- m_request_tracker.insert(req);
- if (req->istexture()) {
- m_icnt_L2_queue->push(req);
- req->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- } else {
- rop_delay_t r;
- r.req = req;
- r.ready_cycle = cycle + m_config->rop_latency;
- m_rop.push(r);
- req->set_status(IN_PARTITION_ROP_DELAY,
- m_gpu->gpu_sim_cycle + m_gpu->gpu_tot_sim_cycle);
- }
+ for(unsigned i=0; i<reqs.size(); ++i) {
+ mem_fetch* req = reqs[i];
+ m_request_tracker.insert(req);
+ if( req->istexture() ) {
+ m_icnt_L2_queue->push(req);
+ req->set_status(IN_PARTITION_ICNT_TO_L2_QUEUE,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ } else {
+ rop_delay_t r;
+ r.req = req;
+ r.ready_cycle = cycle + m_config->rop_latency;
+ m_rop.push(r);
+ req->set_status(IN_PARTITION_ROP_DELAY,m_gpu->gpu_sim_cycle+m_gpu->gpu_tot_sim_cycle);
+ }
+ }
}
- }
}
-mem_fetch *memory_sub_partition::pop() {
- mem_fetch *mf = m_L2_icnt_queue->pop();
- m_request_tracker.erase(mf);
- if (mf && mf->isatomic()) mf->do_atomic();
- if (mf && (mf->get_access_type() == L2_WRBK_ACC ||
- mf->get_access_type() == L1_WRBK_ACC)) {
- delete mf;
- mf = NULL;
- }
- return mf;
+mem_fetch* memory_sub_partition::pop()
+{
+ mem_fetch* mf = m_L2_icnt_queue->pop();
+ m_request_tracker.erase(mf);
+ if ( mf && mf->isatomic() )
+ mf->do_atomic();
+ if( mf && (mf->get_access_type() == L2_WRBK_ACC || mf->get_access_type() == L1_WRBK_ACC) ) {
+ delete mf;
+ mf = NULL;
+ }
+ return mf;
}
-mem_fetch *memory_sub_partition::top() {
- mem_fetch *mf = m_L2_icnt_queue->top();
- if (mf && (mf->get_access_type() == L2_WRBK_ACC ||
- mf->get_access_type() == L1_WRBK_ACC)) {
- m_L2_icnt_queue->pop();
- m_request_tracker.erase(mf);
- delete mf;
- mf = NULL;
- }
- return mf;
+mem_fetch* memory_sub_partition::top()
+{
+ mem_fetch *mf = m_L2_icnt_queue->top();
+ if( mf && (mf->get_access_type() == L2_WRBK_ACC || mf->get_access_type() == L1_WRBK_ACC) ) {
+ m_L2_icnt_queue->pop();
+ m_request_tracker.erase(mf);
+ delete mf;
+ mf = NULL;
+ }
+ return mf;
}
-void memory_sub_partition::set_done(mem_fetch *mf) {
- m_request_tracker.erase(mf);
+void memory_sub_partition::set_done( mem_fetch *mf )
+{
+ m_request_tracker.erase(mf);
}
-void memory_sub_partition::accumulate_L2cache_stats(
- class cache_stats &l2_stats) const {
- if (!m_config->m_L2_config.disabled()) {
- l2_stats += m_L2cache->get_stats();
- }
+void memory_sub_partition::accumulate_L2cache_stats(class cache_stats &l2_stats) const {
+ if (!m_config->m_L2_config.disabled()) {
+ l2_stats += m_L2cache->get_stats();
+ }
}
-void memory_sub_partition::get_L2cache_sub_stats(
- struct cache_sub_stats &css) const {
- if (!m_config->m_L2_config.disabled()) {
- m_L2cache->get_sub_stats(css);
- }
+void memory_sub_partition::get_L2cache_sub_stats(struct cache_sub_stats &css) const{
+ if (!m_config->m_L2_config.disabled()) {
+ m_L2cache->get_sub_stats(css);
+ }
}
-void memory_sub_partition::get_L2cache_sub_stats_pw(
- struct cache_sub_stats_pw &css) const {
- if (!m_config->m_L2_config.disabled()) {
- m_L2cache->get_sub_stats_pw(css);
- }
+void memory_sub_partition::get_L2cache_sub_stats_pw(struct cache_sub_stats_pw &css) const{
+ if (!m_config->m_L2_config.disabled()) {
+ m_L2cache->get_sub_stats_pw(css);
+ }
}
void memory_sub_partition::clear_L2cache_stats_pw() {
- if (!m_config->m_L2_config.disabled()) {
- m_L2cache->clear_pw();
- }
+ if (!m_config->m_L2_config.disabled()) {
+ m_L2cache->clear_pw();
+ }
}
-void memory_sub_partition::visualizer_print(gzFile visualizer_file) {
- // Support for L2 AerialVision stats
- // Per-sub-partition stats would be trivial to extend from this
- cache_sub_stats_pw temp_sub_stats;
- get_L2cache_sub_stats_pw(temp_sub_stats);
+void memory_sub_partition::visualizer_print( gzFile visualizer_file )
+{
+ // Support for L2 AerialVision stats
+ // Per-sub-partition stats would be trivial to extend from this
+ cache_sub_stats_pw temp_sub_stats;
+ get_L2cache_sub_stats_pw(temp_sub_stats);
- m_stats->L2_read_miss += temp_sub_stats.read_misses;
- m_stats->L2_write_miss += temp_sub_stats.write_misses;
- m_stats->L2_read_hit += temp_sub_stats.read_hits;
- m_stats->L2_write_hit += temp_sub_stats.write_hits;
+ m_stats->L2_read_miss += temp_sub_stats.read_misses;
+ m_stats->L2_write_miss += temp_sub_stats.write_misses;
+ m_stats->L2_read_hit += temp_sub_stats.read_hits;
+ m_stats->L2_write_hit += temp_sub_stats.write_hits;
- clear_L2cache_stats_pw();
+ clear_L2cache_stats_pw();
}