diff options
| author | Tor Aamodt <[email protected]> | 2010-10-01 08:55:28 -0800 |
|---|---|---|
| committer | Tor Aamodt <[email protected]> | 2010-10-01 08:55:28 -0800 |
| commit | 11b308e7363e937966b035b4891db32b4eece3bf (patch) | |
| tree | 50ca4c9ad6f163ac4acb2bf505e64dfebed66947 /src/gpgpu-sim/delayqueue.h | |
| parent | bb820c116764d7a1b8e071137d32b74e7f34dd2f (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/delayqueue.h')
| -rw-r--r-- | src/gpgpu-sim/delayqueue.h | 192 |
1 files changed, 154 insertions, 38 deletions
diff --git a/src/gpgpu-sim/delayqueue.h b/src/gpgpu-sim/delayqueue.h index a8d6fc1..8392460 100644 --- a/src/gpgpu-sim/delayqueue.h +++ b/src/gpgpu-sim/delayqueue.h @@ -70,51 +70,167 @@ #ifndef DELAYQUEUE_H #define DELAYQUEUE_H -typedef struct delay_data_t delay_data; -struct delay_data_t { - void *data; - unsigned int time_elapsed; - delay_data *next; +#include "../intersim/statwraper.h" +#include "gpu-misc.h" + +template <class T> +struct fifo_data { + T *m_data; + fifo_data *m_next; unsigned long long push_time; //for stat collection }; -typedef struct { - const char* name; - int uid; +template <class T> +class fifo_pipeline { +public: + fifo_pipeline(const char* nm, unsigned int minlen, unsigned int maxlen, unsigned long long current_time ) + { + m_name = nm; + m_min_len = minlen; + m_max_len = maxlen; + m_length = 0; + m_n_element = 0; + m_head = NULL; + m_tail = NULL; + for (unsigned i=0;i<m_min_len;i++) + push(NULL,current_time); + m_lat_stat = StatCreate(m_name,1,32); + } + + ~fifo_pipeline() + { + while (m_head) { + m_tail = m_head; + m_head = m_head->m_next; + delete m_tail; + } + } + + void push(T* data, unsigned long long current_time ) + { + if (m_max_len) assert(m_length < m_max_len); + if (m_head) { + if (m_tail->m_data || m_length < m_min_len) { + m_tail->m_next = new fifo_data<T>(); + m_tail = m_tail->m_next; + m_length++; + m_n_element++; + } + } else { + m_head = m_tail = new fifo_data<T>(); + m_length++; + m_n_element++; + } + m_tail->m_next = NULL; + m_tail->m_data = data; + m_tail->push_time = current_time; + } + + T* pop( unsigned long long current_time ) + { + fifo_data<T>* next; + T* data; + if (m_head) { + next = m_head->m_next; + data = m_head->m_data; + StatAddSample(m_lat_stat, LOGB2 (current_time - m_head->push_time)); + if ( m_head == m_tail ) { + assert( next == NULL ); + m_tail = NULL; + } + delete m_head; + m_head = next; + m_length--; + if (m_length == 0) { + assert( m_head == NULL ); + m_tail = m_head; + } + m_n_element--; + if (m_min_len && m_length < m_min_len) { + push(NULL,current_time); + m_n_element--; // uncount NULL elements inserted to create delays + } + } else { + data = NULL; + } + return data; + } - unsigned int latency; - unsigned int min_len; - unsigned int max_len; - unsigned int length; - unsigned int n_element; + T* top() + { + if (m_head) { + return m_head->m_data; + } else { + return NULL; + } + } - delay_data *head; - delay_data *tail; + void set_min_length(unsigned int new_min_len, unsigned long long current_time) + { + if (new_min_len == m_min_len) return; + + if (new_min_len > m_min_len) { + m_min_len = new_min_len; + while (m_length < m_min_len) { + push(NULL,current_time); + m_n_element--; // uncount NULL elements inserted to create delays + } + } else { + // in this branch imply that the original min_len is larger then 0 + // ie. head != 0 + assert(m_head); + m_min_len = new_min_len; + while ((m_length > m_min_len) && (m_tail->m_data == 0)) { + fifo_data<T> *iter; + iter = m_head; + while (iter && (iter->m_next != m_tail)) + iter = iter->m_next; + if (!iter) { + // there is only one node, and that node is empty + assert(m_head->m_data == 0); + pop(current_time); + } else { + // there are more than one node, and tail node is empty + assert(iter->m_next == m_tail); + delete m_tail; + m_tail = iter; + m_tail->m_next = 0; + m_length--; + } + } + } + } - void* lat_stat; //a pointer to latency stats distribution structure - //occupancy stat - unsigned int max_size_stat; - unsigned int n_stat_samples; - float avg_size_stat; -} delay_queue; + bool full() const { return (m_max_len && m_length >= m_max_len); } + bool empty() const { return m_head == NULL; } + unsigned get_n_element() const { return m_n_element; } + unsigned get_length() const { return m_length; } + unsigned get_max_len() const { return m_max_len; } + void* get_lat_stat() { return m_lat_stat; } -unsigned char dq_full(delay_queue* dq ); -unsigned char dq_empty(delay_queue* dq ); -unsigned int dq_n_element(delay_queue* dq ); -unsigned char dq_push(delay_queue* dq, void* data); -void* dq_pop(delay_queue* dq); -void dq_set_min_length(delay_queue* dq, unsigned int new_min_len); -void removeEntry(void* data, delay_queue** dq, int size_dq); -delay_queue* dq_create( const char* name, - unsigned int latency, - unsigned int min_len, - unsigned int max_len); -void dq_remove(void* data, delay_queue* dq); -void dq_print(delay_queue* dq); -void dq_free(delay_queue* dq); -void* dq_top(delay_queue* dq);//return the data in the head without poping the queue + void print() const + { + fifo_data<T>* ddp = m_head; + printf("%s(%d): ", m_name, m_length); + while (ddp) { + printf("%p ", ddp->m_data); + ddp = ddp->m_next; + } + printf("\n"); + } -void dq_update_stat(delay_queue* dq); -void dq_print_stat(delay_queue* dq); +private: + const char* m_name; + + unsigned int m_min_len; + unsigned int m_max_len; + unsigned int m_length; + unsigned int m_n_element; + + fifo_data<T> *m_head; + fifo_data<T> *m_tail; + + void* m_lat_stat; //a pointer to latency stats distribution structure +}; #endif |
