// Copyright (c) 2009-2011, Tor M. Aamodt, Wilson W.L. Fung, // The University of British Columbia // All rights reserved. // // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are met: // // 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 // 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 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "visualizer.h" #include "gpu-sim.h" #include "l2cache.h" #include "shader.h" #include "../option_parser.h" #include "mem_latency_stat.h" #include "stat-tool.h" #include "gpu-cache.h" #include #include #include static void time_vector_print_interval2gzfile(gzFile outfile); void gpgpu_sim::visualizer_printstat() { gzFile visualizer_file = NULL; // gzFile is basically a pointer to a struct, so it is fine to initialize it as NULL if ( !m_config.g_visualizer_enabled ) return; // clean the content of the visualizer log if it is the first time, otherwise attach at the end static bool visualizer_first_printstat = true; visualizer_file = gzopen(m_config.g_visualizer_filename, (visualizer_first_printstat)? "w" : "a"); if (visualizer_file == NULL) { printf("error - could not open visualizer trace file.\n"); exit(1); } gzsetparams(visualizer_file, m_config.g_visualizer_zlevel, Z_DEFAULT_STRATEGY); visualizer_first_printstat = false; cflog_visualizer_gzprint(visualizer_file); shader_CTA_count_visualizer_gzprint(visualizer_file); for (unsigned i=0;im_n_mem;i++) m_memory_partition_unit[i]->visualizer_print(visualizer_file); m_shader_stats->visualizer_print(visualizer_file); m_memory_stats->visualizer_print(visualizer_file); // other parameters for graphing gzprintf(visualizer_file, "globalcyclecount: %lld\n", gpu_sim_cycle); gzprintf(visualizer_file, "globalinsncount: %lld\n", gpu_sim_insn); gzprintf(visualizer_file, "globaltotinsncount: %lld\n", gpu_tot_sim_insn); time_vector_print_interval2gzfile(visualizer_file); gzclose(visualizer_file); /* gzprintf(visualizer_file, "CacheMissRate_GlobalLocalL1_All: "); for (unsigned i=0;iL1_windowed_cache_miss_rate(0)); gzprintf(visualizer_file, "\n"); gzprintf(visualizer_file, "CacheMissRate_TextureL1_All: "); for (unsigned i=0;iL1tex_windowed_cache_miss_rate(0)); gzprintf(visualizer_file, "\n"); gzprintf(visualizer_file, "CacheMissRate_ConstL1_All: "); for (unsigned i=0;iL1const_windowed_cache_miss_rate(0)); gzprintf(visualizer_file, "\n"); gzprintf(visualizer_file, "CacheMissRate_GlobalLocalL1_noMgHt: "); for (unsigned i=0;iL1_windowed_cache_miss_rate(1)); gzprintf(visualizer_file, "\n"); gzprintf(visualizer_file, "CacheMissRate_TextureL1_noMgHt: "); for (unsigned i=0;iL1tex_windowed_cache_miss_rate(1)); gzprintf(visualizer_file, "\n"); gzprintf(visualizer_file, "CacheMissRate_ConstL1_noMgHt: "); for (unsigned i=0;iL1const_windowed_cache_miss_rate(1)); gzprintf(visualizer_file, "\n"); // reset for next interval for (unsigned i=0;inew_cache_window(); */ } #include #include #include #include #include"../gpgpu-sim/shader.h" class my_time_vector { private: std::map< unsigned int, std::vector > ld_time_map; std::map< unsigned int, std::vector > st_time_map; unsigned ld_vector_size; unsigned st_vector_size; std::vector ld_time_dist; std::vector st_time_dist; std::vector overal_ld_time_dist; std::vector overal_st_time_dist; int overal_ld_count; int overal_st_count; public: my_time_vector(int ld_size,int st_size){ ld_vector_size = ld_size; st_vector_size = st_size; ld_time_dist.resize(ld_size); st_time_dist.resize(st_size); overal_ld_time_dist.resize(ld_size); overal_st_time_dist.resize(st_size); overal_ld_count = 0; overal_st_count= 0; } void update_ld(unsigned int uid,unsigned int slot, long int time) { if ( ld_time_map.find( uid )!=ld_time_map.end() ) { ld_time_map[uid][slot]=time; } else if (slot < NUM_MEM_REQ_STAT ) { std::vector time_vec; time_vec.resize(ld_vector_size); time_vec[slot] = time; ld_time_map[uid] = time_vec; } else { //It's a merged mshr! forget it } } void update_st(unsigned int uid,unsigned int slot, long int time) { if ( st_time_map.find( uid )!=st_time_map.end() ) { st_time_map[uid][slot]=time; } else { std::vector time_vec; time_vec.resize(st_vector_size); time_vec[slot] = time; st_time_map[uid] = time_vec; } } void check_ld_update(unsigned int uid,unsigned int slot, long int latency) { if ( ld_time_map.find( uid )!=ld_time_map.end() ) { int our_latency = ld_time_map[uid][slot] - ld_time_map[uid][IN_ICNT_TO_MEM]; assert( our_latency == latency); } else if (slot < NUM_MEM_REQ_STAT ) { abort(); } } void check_st_update(unsigned int uid,unsigned int slot, long int latency) { if ( st_time_map.find( uid )!=st_time_map.end() ) { int our_latency = st_time_map[uid][slot] - st_time_map[uid][IN_ICNT_TO_MEM]; assert( our_latency == latency); } else { abort(); } } private: void calculate_ld_dist(void) { unsigned i,first; long int last_update,diff; int finished_count=0; ld_time_dist.clear(); ld_time_dist.resize(ld_vector_size); std::map< unsigned int, std::vector >::iterator iter, iter_temp; iter =ld_time_map.begin() ; while (iter != ld_time_map.end()) { last_update=0; first=-1; if (!iter->second[IN_SHADER_FETCHED]) { //this request is not done yet skip it! ++iter; continue; } while ( !last_update ) { first++; assert( first < iter->second.size() ); last_update = iter->second[first]; } for ( i=first;isecond[i] - last_update; if ( diff>0 ) { ld_time_dist[i]+=diff; last_update = iter->second[i]; } } iter_temp = iter; iter++; ld_time_map.erase(iter_temp); finished_count++; } if ( finished_count ) { for ( i=0;i >::iterator iter,iter_temp; iter =st_time_map.begin() ; while ( iter != st_time_map.end() ) { last_update=0; first=-1; if (!iter->second[IN_SHADER_FETCHED]) { //this request is not done yet skip it! ++iter; continue; } while ( !last_update ) { first++; assert( first < iter->second.size() ); last_update = iter->second[first]; } for ( i=first;isecond[i] - last_update; if ( diff>0 ) { st_time_dist[i]+=diff; last_update = iter->second[i]; } } iter_temp = iter; iter++; st_time_map.erase(iter_temp); finished_count++; } if ( finished_count ) { for ( i=0;i >::iterator iter; for ( iter =ld_time_map.begin() ; iter != ld_time_map.end(); ++iter ) { std::cout<<"ld_uid"<first; for ( i=0;isecond[i]; } std::cout<< std::endl; } } void print_all_st(void) { unsigned i; std::map< unsigned int, std::vector >::iterator iter; for ( iter =st_time_map.begin() ; iter != st_time_map.end(); ++iter ) { std::cout<<"st_uid"<first; for ( i=0;isecond[i]; } std::cout<print_dist(); } void time_vector_print_interval2gzfile(gzFile outfile) { g_my_time_vector->print_to_gzfile(outfile); } #include "../gpgpu-sim/mem_fetch.h" void time_vector_update(unsigned int uid,int slot ,long int cycle,int type) { if ( (type == READ_REQUEST) || (type == READ_REPLY) ) { g_my_time_vector->update_ld( uid, slot,cycle); } else if ( (type == WRITE_REQUEST) || (type == WRITE_ACK) ) { g_my_time_vector->update_st( uid, slot,cycle); } else { abort(); } } void check_time_vector_update(unsigned int uid,int slot ,long int latency,int type) { if ( (type == READ_REQUEST) || (type == READ_REPLY) ) { g_my_time_vector->check_ld_update( uid, slot, latency ); } else if ( (type == WRITE_REQUEST) || (type == WRITE_ACK) ) { g_my_time_vector->check_st_update( uid, slot, latency ); } else { abort(); } }