summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorsspenst <[email protected]>2016-08-05 14:45:56 -0700
committersspenst <[email protected]>2016-08-05 14:45:56 -0700
commitd1b45cf53a39261663a3eff0d409d6c1220d923d (patch)
tree85ab2442c3f6e581195650626c8e8586eed9e8b9 /src
parent9a6b68c5b11fbdb239d25afe60e5135bc2afa88d (diff)
Added ptx_warp_info to know how many threads within a warp have executed
Diffstat (limited to 'src')
-rw-r--r--src/abstract_hardware_model.h2
-rw-r--r--src/cuda-sim/cuda-sim.cc10
-rw-r--r--src/cuda-sim/instructions.cc93
-rw-r--r--src/cuda-sim/ptx_sim.cc21
-rw-r--r--src/cuda-sim/ptx_sim.h12
5 files changed, 94 insertions, 44 deletions
diff --git a/src/abstract_hardware_model.h b/src/abstract_hardware_model.h
index 13dfce3..cfa8c9f 100644
--- a/src/abstract_hardware_model.h
+++ b/src/abstract_hardware_model.h
@@ -1028,6 +1028,7 @@ class core_t {
m_warp_count += 1;
}
assert( m_warp_count * m_warp_size > 0 );
+ //m_warp = ( ptx_warp_info** )calloc( m_warp_count, sizeof( ptx_warp_info* ) );
m_thread = ( ptx_thread_info** )
calloc( m_warp_count * m_warp_size,
sizeof( ptx_thread_info* ) );
@@ -1063,6 +1064,7 @@ class core_t {
class gpgpu_sim *m_gpu;
kernel_info_t *m_kernel;
simt_stack **m_simt_stack; // pdom based reconvergence context for each warp
+ //class ptx_warp_info ** m_warp;
class ptx_thread_info ** m_thread;
unsigned m_warp_size;
unsigned m_warp_count;
diff --git a/src/cuda-sim/cuda-sim.cc b/src/cuda-sim/cuda-sim.cc
index 337463b..ba0d00b 100644
--- a/src/cuda-sim/cuda-sim.cc
+++ b/src/cuda-sim/cuda-sim.cc
@@ -1417,6 +1417,7 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel,
static std::map<unsigned,memory_space*> shared_memory_lookup;
static std::map<unsigned,memory_space*> sstarr_memory_lookup;
static std::map<unsigned,ptx_cta_info*> ptx_cta_lookup;
+ static std::map<unsigned,ptx_warp_info*> ptx_warp_lookup;
static std::map<unsigned,std::map<unsigned,memory_space*> > local_memory_lookup;
if ( *thread_info != NULL ) {
@@ -1501,6 +1502,15 @@ unsigned ptx_sim_init_thread( kernel_info_t &kernel,
new_tid += tid;
ptx_thread_info *thd = new ptx_thread_info(kernel);
+ ptx_warp_info *warp_info = NULL;
+ if ( ptx_warp_lookup.find(hw_warp_id) == ptx_warp_lookup.end() ) {
+ warp_info = new ptx_warp_info(); // num_threads should be threads in the warp
+ ptx_warp_lookup[hw_warp_id] = warp_info;
+ } else {
+ warp_info = ptx_warp_lookup[hw_warp_id];
+ }
+ thd->m_warp_info = warp_info;
+
memory_space *local_mem = NULL;
std::map<unsigned,memory_space*>::iterator l = local_mem_lookup.find(new_tid);
if ( l != local_mem_lookup.end() ) {
diff --git a/src/cuda-sim/instructions.cc b/src/cuda-sim/instructions.cc
index f58c4f5..9dcc25c 100644
--- a/src/cuda-sim/instructions.cc
+++ b/src/cuda-sim/instructions.cc
@@ -1471,74 +1471,81 @@ void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst )
// 7 = synapse value
// 8 = output value
- // TODO: what should happen when the output precision is larger than the input precision?
- // TODO: create a ptx_warp_info that can do the same thing that ptx_cta_info does here
- ptx_cta_info *cta_info = core->get_thread_info()[inst.warp_id() * core->get_warp_size()]->m_cta_info;
- const int NUM_THREADS = cta_info->num_threads();
- const int NUM_BUFFERS = 4;
- cta_info->inc_bar_threads();
+ const operand_info &dst = pI->dst();
+ const operand_info &src1 = pI->src1();
+ const operand_info &src2 = pI->src2();
+ unsigned type = pI->get_type();
+ int tid = inst.warp_id() * core->get_warp_size();
+ ptx_thread_info *thread = core->get_thread_info()[tid];
+ const int ip = (thread->get_operand_value(src1, dst, type, thread, 1)).u32;
+ const int op = (thread->get_operand_value(src2, dst, type, thread, 1)).u32;
+ const int THREADS = inst.active_count();
+ const int INBUFFERS = 4;
+ const int OUTBUFFERS = (((32/ip)*INBUFFERS) / (32/op)) + ((((32/ip)*INBUFFERS) % (32/op)) != 0);
+ if (OUTBUFFERS > THREADS) {
+ printf("GPGPU-Sim PTX: BSMAD ERROR - Number of output registers required (%d) is greater than the number available (%d)\n", OUTBUFFERS, THREADS);
+ abort();
+ }
+ ptx_warp_info *warp_info = core->get_thread_info()[inst.warp_id() * core->get_warp_size()]->m_warp_info;
+ warp_info->inc_done_threads();
// threads within the warp are executed sequentially by the simulator, store output in first four registers
- if (cta_info->get_bar_threads() <= NUM_BUFFERS) {
- unsigned ip, op; // only get these when i = 0
- unsigned buffer[inst.active_count()][NUM_BUFFERS];
+ if (warp_info->get_done_threads() <= OUTBUFFERS) {
+ unsigned buffer[inst.active_count()][INBUFFERS];
unsigned synapse[inst.active_count()];
- unsigned output[NUM_BUFFERS];
+ unsigned output;
// loop through all threads in the warp and get all data
for (unsigned i = 0, j = 0; i < core->get_warp_size(); i++) {
if (inst.active(i)) {
- const operand_info dst = pI->dst();
- const operand_info src1 = pI->operand_lookup(1);
- const operand_info src2 = pI->operand_lookup(2);
- const operand_info src3 = pI->operand_lookup(3);
- const operand_info src4 = pI->operand_lookup(4);
- const operand_info src5 = pI->operand_lookup(5);
- const operand_info src6 = pI->operand_lookup(6);
- const operand_info src7 = pI->operand_lookup(7);
- const operand_info src8 = pI->operand_lookup(8);
- unsigned type = pI->get_type();
-
- int tid = inst.warp_id() * core->get_warp_size() + i;
- ptx_thread_info *thread = core->get_thread_info()[tid];
+ const operand_info &src3 = pI->operand_lookup(3);
+ const operand_info &src4 = pI->operand_lookup(4);
+ const operand_info &src5 = pI->operand_lookup(5);
+ const operand_info &src6 = pI->operand_lookup(6);
+ const operand_info &src7 = pI->operand_lookup(7);
+ const operand_info &src8 = pI->operand_lookup(8);
- // only get precision data once
- if (j == 0) {
- ip = (thread->get_operand_value(src1, dst, type, thread, 1)).u32;
- op = (thread->get_operand_value(src2, dst, type, thread, 1)).u32;
- }
+ thread = core->get_thread_info()[tid+i];
// get buffer data and synapse data from each thread
buffer[j][0] = (thread->get_operand_value(src3, dst, type, thread, 1)).u32;
buffer[j][1] = (thread->get_operand_value(src4, dst, type, thread, 1)).u32;
buffer[j][2] = (thread->get_operand_value(src5, dst, type, thread, 1)).u32;
buffer[j][3] = (thread->get_operand_value(src6, dst, type, thread, 1)).u32;
synapse[j] = (thread->get_operand_value(src7, dst, type, thread, 1)).u32;
+ j++;
// get output data from the first 4 threads
- if (j < NUM_BUFFERS) {
- output[j] = (thread->get_operand_value(src8, dst, type, thread, 1)).u32;
+ if (j == warp_info->get_done_threads()) {
+ output = (thread->get_operand_value(src8, dst, type, thread, 1)).u32;
}
- j++;
}
}
// unpack registers, compute enough outputs to fill an output register
unsigned *unpacked_output = (unsigned*)calloc(32/op,sizeof(unsigned));
- unsigned buffer_data_start = (32/op)*(cta_info->get_bar_threads()-1);
- for (unsigned i = buffer_data_start; i < (32/op + buffer_data_start) && i < (32/ip)*NUM_BUFFERS; i++) {
+ unsigned buffer_data_start = (32/op)*(warp_info->get_done_threads()-1);
+ for (unsigned i = buffer_data_start; i < (32/op + buffer_data_start) && i < (32/ip)*INBUFFERS; i++) {
unsigned buf = i/(32/ip);
unsigned pos = i%(32/ip);
-
unsigned mask = 0;
+ int sum = 0;
+ // sum values from the buffers
for (int b = 0; b < ip; b++) {
mask |= (1 << b);
}
mask <<= (pos*ip);
- int sum = 0;
- for (int j = 0; j < NUM_THREADS; j++) {
+ for (int j = 0; j < THREADS; j++) {
sum += (mask & buffer[j][buf]) >> (pos*ip);
}
- unpacked_output[i - buffer_data_start] = sum;
+ // get the previous output
+ mask = 0;
+ for (int b = 0; b < op; b++) {
+ mask |= (1 << b);
+ }
+ mask <<= (op*(i-buffer_data_start));
+ int past_output = (mask & output) >> (op*(i-buffer_data_start));
+
+ unpacked_output[i-buffer_data_start] = sum + past_output;
}
// truncate output
@@ -1575,11 +1582,8 @@ void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst )
// store the result in the correct thread's output register
for (unsigned i = 0, j = 0; i < core->get_warp_size(); i++) {
if (inst.active(i)) j++;
- if (j == cta_info->get_bar_threads()) {
- const operand_info &dst = pI->dst();
- unsigned type = pI->get_type();
- int tid = inst.warp_id() * core->get_warp_size() + i;
- ptx_thread_info *thread = core->get_thread_info()[tid];
+ if (j == warp_info->get_done_threads()) {
+ thread = core->get_thread_info()[tid+i];
ptx_reg_t data;
data.u32 = output_data;
thread->set_operand_value(dst, data, type, thread, pI);
@@ -1588,8 +1592,9 @@ void bsmad_impl( const ptx_instruction *pI, core_t *core, warp_inst_t inst )
}
}
- if (cta_info->get_bar_threads() == NUM_THREADS) {
- cta_info->reset_bar_threads();
+ // once the warp has finished, set the number of completed threads back to 0 for the next warp
+ if (warp_info->get_done_threads() == THREADS) {
+ warp_info->reset_done_threads();
}
}
diff --git a/src/cuda-sim/ptx_sim.cc b/src/cuda-sim/ptx_sim.cc
index f48115b..820287d 100644
--- a/src/cuda-sim/ptx_sim.cc
+++ b/src/cuda-sim/ptx_sim.cc
@@ -144,6 +144,26 @@ void ptx_cta_info::reset_bar_threads()
m_bar_threads = 0;
}
+ptx_warp_info::ptx_warp_info()
+{
+ reset_done_threads();
+}
+
+unsigned ptx_warp_info::get_done_threads() const
+{
+ return m_done_threads;
+}
+
+void ptx_warp_info::inc_done_threads()
+{
+ m_done_threads++;
+}
+
+void ptx_warp_info::reset_done_threads()
+{
+ m_done_threads = 0;
+}
+
unsigned g_ptx_thread_info_uid_next=1;
unsigned g_ptx_thread_info_delete_count=0;
@@ -170,6 +190,7 @@ ptx_thread_info::ptx_thread_info( kernel_info_t &kernel )
m_branch_taken = 0;
m_shared_mem = NULL;
m_sstarr_mem = NULL;
+ m_warp_info = NULL;
m_cta_info = NULL;
m_local_mem = NULL;
m_symbol_table = NULL;
diff --git a/src/cuda-sim/ptx_sim.h b/src/cuda-sim/ptx_sim.h
index 4e748e9..c62fa57 100644
--- a/src/cuda-sim/ptx_sim.h
+++ b/src/cuda-sim/ptx_sim.h
@@ -171,6 +171,17 @@ private:
std::set<ptx_thread_info*> m_dangling_pointers;
};
+class ptx_warp_info {
+public:
+ ptx_warp_info(); // add get_core or something, or threads?
+ unsigned get_done_threads() const;
+ void inc_done_threads();
+ void reset_done_threads();
+
+private:
+ unsigned m_done_threads;
+};
+
class symbol;
struct stack_entry {
@@ -430,6 +441,7 @@ public:
memory_space *m_shared_mem;
memory_space *m_sstarr_mem;
memory_space *m_local_mem;
+ ptx_warp_info *m_warp_info;
ptx_cta_info *m_cta_info;
ptx_reg_t m_last_set_operand_value;