summaryrefslogtreecommitdiff
path: root/src/gpgpu-sim/warp_tracker.h
diff options
context:
space:
mode:
authorTor Aamodt <[email protected]>2010-10-01 08:55:28 -0800
committerTor Aamodt <[email protected]>2010-10-01 08:55:28 -0800
commit11b308e7363e937966b035b4891db32b4eece3bf (patch)
tree50ca4c9ad6f163ac4acb2bf505e64dfebed66947 /src/gpgpu-sim/warp_tracker.h
parentbb820c116764d7a1b8e071137d32b74e7f34dd2f (diff)
integrating recent changes from fermi-test into fermi
(i'll use "fermi" for more disruptive changes to the pipeline model such as updating the MSHRs and getting rid of the warp tracker, ripping out DWF, etc...) [git-p4: depot-paths = "//depot/gpgpu_sim_research/fermi/distribution/": change = 7805]
Diffstat (limited to 'src/gpgpu-sim/warp_tracker.h')
-rw-r--r--src/gpgpu-sim/warp_tracker.h281
1 files changed, 152 insertions, 129 deletions
diff --git a/src/gpgpu-sim/warp_tracker.h b/src/gpgpu-sim/warp_tracker.h
index 1e2e5e0..8397a81 100644
--- a/src/gpgpu-sim/warp_tracker.h
+++ b/src/gpgpu-sim/warp_tracker.h
@@ -63,176 +63,199 @@
* Vancouver, BC V6T 1Z4
*/
-#include <vector>
-#include <map>
-#include <list>
-
#ifndef warp_tracker_h_INCLUDED
#define warp_tracker_h_INCLUDED
-#ifdef __cplusplus
-
- #include <cstdio>
- #include <cstdlib>
- #include <cstring>
- #include <cassert>
- #include <map>
- #include <list>
- #include <deque>
- #include <queue>
-
-#endif
+#include <cstdio>
+#include <cstdlib>
+#include <cstring>
+#include <cassert>
+#include <map>
+#include <list>
+#include <deque>
+#include <queue>
+#include <vector>
+#include <map>
+#include <list>
#include "../abstract_hardware_model.h"
#include "shader.h"
-extern unsigned int warp_size;
-extern unsigned int gpu_n_shader;
-extern unsigned int gpu_n_thread_per_shader;
-
-//void init_warp_tracker( );
-
-//void wpt_register_warp( int *tid_in, shader_core_ctx_t *shd );
-
-//int wpt_signal_avail( int tid, shader_core_ctx_t *shd );
-
-//void wpt_unlock_threads( int tid, shader_core_ctx_t *shd );
-
-//int wpt_signal_complete( int tid, shader_core_ctx_t *shd );
-
void print_thread_pc_histogram( FILE *fout );
-void print_thread_pc( FILE *fout );
-void track_thread_pc( int shader_id, int *tid, address_type pc );
-
-int* alloc_commit_warp( );
-void free_commit_warp( int *commit_warp );
+void print_thread_pc( FILE *fout, unsigned n_shader );
class warp_tracker {
public:
- std::vector<int> tid;
-
- int n_thd; // total number of threads in this warp
- int n_notavail; // number of threads still not available
- shader_core_ctx_t *shd; // reference to shader core
- address_type pc;
-
- warp_tracker () {
- tid.resize(warp_size,-1);
-
- n_thd = 0;
- n_notavail = 0;
- shd = NULL;
+ warp_tracker( int *tid, address_type pc, unsigned warp_size )
+ {
+ // makes a copy of pc and thread ids in warp
+ m_pc = pc;
+ m_n_thd = 0;
+ m_warp_size=warp_size;
+ m_tid.reserve(warp_size);
+ std::copy(tid, tid+warp_size, m_tid.begin());
+ for (unsigned i=0; i<warp_size; i++)
+ if (tid[i] >= 0) m_n_thd++;
+ m_n_notavail = m_n_thd;
}
- void print_info(){
- printf("sid=%d ", shd->sid);
-
- printf("tid=[");
- for(unsigned i=0; i<warp_size; i++)
- if(tid[i] > -1)
- printf("%d ", tid[i]);
+ void print_info( unsigned sid ) const
+ {
+ printf("sid=%d tid=[", sid);
+ for(unsigned i=0; i<m_tid.size(); i++)
+ if(m_tid[i] > -1) printf("%d ", m_tid[i]);
printf("]\n");
}
+ unsigned warp_size() const { return m_warp_size; }
+ address_type pc() const { return m_pc; }
+ int tid(unsigned i) const { return m_tid[i]; }
- void copy_tid( int *tid ) {
- std::copy(tid, tid+warp_size, this->tid.begin());
+ bool avail_thd()
+ {
+ // signal that this thread is available for fetch
+ // if all threads in the warp are available, change all their status
+ // and return true
+ assert( m_n_notavail > 0 );
+ m_n_notavail--;
+ return (m_n_notavail==0);
}
- // set the warp to be consist of the given threads
- void set_warp ( int *tid, shader_core_ctx_t *shd, address_type pc) {
- copy_tid(tid);
-
- this->n_thd = 0;
- this->n_notavail = 0;
- for (unsigned i=0; i<warp_size; i++) {
- if (this->tid[i] >= 0) {
- this->n_thd++;
- }
- }
- this->n_notavail = this->n_thd;
- this->shd = shd;
- this->pc = pc;
- }
-
- // signal that this thread is available for fetch
- // if all threads in the warp are available, change all their status
- // and return true
- bool avail_thd ( ) {
- n_notavail--;
- return (n_notavail==0);
- }
-
- // a bookkeeping method to allow a warp to be deallocated
- // when its threads have finished executing.
- bool complete_thd ( int tid_in ) {
- n_notavail--;
- if (n_notavail) {
+ bool complete_thd( int tid_in )
+ {
+ // a bookkeeping method to allow a warp to be deallocated
+ // when its threads have finished executing.
+ assert( m_n_notavail > 0 );
+ m_n_notavail--;
+ if (m_n_notavail) {
return false;
} else {
return true;
}
}
+
+private:
+ address_type m_pc;
+ std::vector<int> m_tid;
+ int m_n_thd; // total number of threads in this warp with active mask set to enabled
+ int m_n_notavail; // number of threads waiting (preventing this warp from being issued again)
+ unsigned m_warp_size;
};
-//-------------------------------------------------------------------
-class warp_tracker_pool
-{
- private:
- unsigned gpu_n_shader;
- unsigned gpu_n_thread_per_shader;
+class warp_tracker_pool {
+public:
+ warp_tracker_pool( class shader_core_ctx *my_shader );
+
+ void wpt_register_warp( int *tid_in, address_type pc, unsigned n_thread_in_warp, unsigned warp_size );
+ int wpt_signal_avail( int tid, address_type pc );
+ void wpt_deregister_warp( int tid, address_type pc );
+ int wpt_signal_complete( int tid, address_type pc );
+ bool wpt_thread_in_wpt( int tid );
- // Warp tracker map: a vector (index shader id) of vectors (index thread id) of maps (index pc)
- std::vector< std::vector< std::map<address_type, warp_tracker*> > > warp_tracker_map;
+private:
+ warp_tracker* map_get_warp_tracker(int tid, address_type pc) {
+ // Returns NULL pointer if no warp_tracker assigned
+ if(warp_tracker_map[tid].find(pc) == warp_tracker_map[tid].end())
+ return NULL;
+ return warp_tracker_map[tid][pc];
+ }
- // Pool of warp trackers
- std::list<warp_tracker> warp_tracker_list;
+ void map_set_warp_tracker(int tid, address_type pc, warp_tracker* wpt) {
+ // Make sure that warp tracker is not already assigned here
+ if(warp_tracker_map[tid].find(pc) != warp_tracker_map[tid].end())
+ assert(warp_tracker_map[tid][pc] == NULL);
+ warp_tracker_map[tid][pc] = wpt;
+ }
- // List to keep track of free warp trackers
- std::list<warp_tracker*> warp_tracker_free_list;
+ void map_clear_warp_tracker( warp_tracker *wpt ) {
+ // Make sure that warp tracker was previously assigned
+ address_type pc = wpt->pc();
+ for (unsigned i=0; i<wpt->warp_size(); i++) {
+ int tid = wpt->tid(i);
+ if (tid >= 0) {
+ assert(warp_tracker_map[tid].find(pc) != warp_tracker_map[tid].end());
+ assert(warp_tracker_map[tid][pc] != NULL);
+ warp_tracker_map[tid][pc] = NULL;
+ }
+ }
+ }
- warp_tracker* map_get_warp_tracker(int sid, int tid, address_type pc) {
- // Return NULL pointer if no warp_tracker assigned
- if(warp_tracker_map[sid][tid].find(pc) == warp_tracker_map[sid][tid].end())
- return NULL;
+// data
- return warp_tracker_map[sid][tid][pc];
- }
+ class shader_core_ctx *m_shader;
+ unsigned gpu_n_thread_per_shader;
+ unsigned warp_size;
- void map_set_warp_tracker(int sid, int tid, address_type pc, warp_tracker* wpt) {
- // Make sure that warp tracker is not already assigned here
- if(warp_tracker_map[sid][tid].find(pc) != warp_tracker_map[sid][tid].end())
- assert(warp_tracker_map[sid][tid][pc] == NULL);
+ // Warp tracker map: vector (index thread id) of maps (index pc)
+ std::vector< std::map<address_type, warp_tracker*> > warp_tracker_map;
+};
+
+class thread_pc_tracker {
+public:
+ address_type *thd_pc; // tracks the pc of each thread
+ std::map<address_type, unsigned> pc_count;
+ unsigned acc_pc_count;
+ int simd_width;
+ static std::map<unsigned, unsigned> histogram; // static so automatically aggregated across cores
- warp_tracker_map[sid][tid][pc] = wpt;
- }
+ thread_pc_tracker( ) {
+ this->acc_pc_count = 0;
+ this->simd_width = 0;
+ this->thd_pc = NULL;
+ }
- void map_clear_warp_tracker(int sid, int tid, address_type pc) {
- // Make sure that warp tracker was previously assigned
- assert(warp_tracker_map[sid][tid].find(pc) != warp_tracker_map[sid][tid].end());
- assert(warp_tracker_map[sid][tid][pc] != NULL);
+ thread_pc_tracker(int simd_width, int thread_count) {
+ this->acc_pc_count = 0;
+ this->simd_width = simd_width;
+ this->thd_pc = new address_type[thread_count];
+ memset( this->thd_pc, 0, sizeof(address_type)*thread_count);
+ }
- warp_tracker_map[sid][tid][pc] = NULL;
- }
+ void add_threads( int *tid, address_type pc ) {
+ for (int i=0; i<simd_width; i++) {
+ if (tid[i] != -1) {
+ pc_count[pc] += 1; // automatically create a new entry if not exist
+ thd_pc[tid[i]] = pc;
+ }
+ }
+ }
- warp_tracker* alloc_warp_tracker( int *tid_in, shader_core_ctx_t *shd, address_type pc );
- void free_warp_tracker(warp_tracker* wpt);
+ void sub_threads( int *tid ) {
+ for (int i=0; i<simd_width; i++) {
+ if (tid[i] != -1) {
+ address_type pc = thd_pc[tid[i]];
+ if (pc == 0) break;
+ pc_count[pc] -= 1;
+ assert((int)pc_count[pc] >= 0);
+ if (pc_count[pc] == 0) pc_count.erase(pc); // manually erasing entries with 0 count
+ }
+ }
+ }
- public:
- warp_tracker_pool( unsigned gpu_n_shader, unsigned gpu_n_thread_per_shader );
+ void update_acc_count( ) {
+ acc_pc_count += pc_count.size();
+ histogram[pc_count.size()] += 1;
+ }
- void wpt_register_warp( int *tid_in, shader_core_ctx_t *shd, address_type pc );
- int wpt_signal_avail( int tid, shader_core_ctx_t *shd, address_type pc );
- void wpt_deregister_warp( int tid, shader_core_ctx_t *shd, address_type pc );
- int wpt_signal_complete( int tid, shader_core_ctx_t *shd, address_type pc );
+ void set_threads_pc ( int *tid, address_type pc ) {
+ sub_threads(tid);
+ add_threads(tid, pc);
+ update_acc_count( );
+ }
- unsigned size() { return warp_tracker_list.size(); }
- unsigned free_size() { return warp_tracker_free_list.size(); }
+ unsigned get_acc_pc_count( ) { return acc_pc_count;}
- bool wpt_thread_in_wpt(shader_core_ctx *shd, int tid);
+ unsigned count( ) { return pc_count.size();}
+ static void histo_print( FILE* fout ) {
+ if (histogram.empty()) return; // do not output anything if the histogram is empty
+ std::map<unsigned, unsigned>::iterator i;
+ fprintf(fout, "Thread PC Histogram: ");
+ for (i = histogram.begin(); i != histogram.end(); i++) {
+ fprintf(fout, "%d:%d ", i->first, i->second);
+ }
+ fprintf(fout, "\n");
+ }
};
-warp_tracker_pool& get_warp_tracker_pool();
-
#endif