void frm_grid_run(struct frm_grid_t *grid) { struct frm_threadblock_t *threadblock, *threadblock_next; struct frm_warp_t *warp, *warp_next; unsigned long long int cycle = 0; /* Set all ready threadblocks to running */ while ((threadblock = grid->pending_list_head)) { frm_threadblock_clear_status(threadblock, frm_threadblock_pending); frm_threadblock_set_status(threadblock, frm_threadblock_running); } /* Set is in state 'running' */ frm_grid_clear_status(grid, frm_grid_pending); frm_grid_set_status(grid, frm_grid_running); /* Execution loop */ while (grid->running_list_head) { /* Stop if maximum number of GPU cycles exceeded */ if (frm_emu_max_cycles && cycle >= frm_emu_max_cycles) esim_finish = esim_finish_frm_max_cycles; /* Stop if maximum number of GPU instructions exceeded */ if (frm_emu_max_inst && frm_emu->inst_count >= frm_emu_max_inst) esim_finish = esim_finish_frm_max_inst; /* Stop if any reason met */ if (esim_finish) break; /* Next cycle */ cycle++; /* Execute an instruction from each work-group */ for (threadblock = grid->running_list_head; threadblock; threadblock = threadblock_next) { /* Save next running work-group */ threadblock_next = threadblock->running_list_next; /* Run an instruction from each warp */ for (warp = threadblock->running_list_head; warp; warp = warp_next) { /* Save next running warp */ warp_next = warp->running_list_next; /* Execute instruction in warp */ frm_warp_execute(warp); } } } /* Dump stats */ frm_grid_dump(grid, stdout); /* Stop if maximum number of functions reached */ //if (frm_emu_max_functions && frm_emu->grid_count >= frm_emu_max_functions) // x86_emu_finish = x86_emu_finish_max_gpu_functions; }
int FrmEmuRun(Emu *self) { FrmEmu *emu = asFrmEmu(self); struct frm_grid_t *grid; struct frm_thread_block_t *thread_block; struct frm_warp_t *warp; /* Stop emulation if no grid needs running */ if (!list_count(emu->grids)) return FALSE; /* Remove grid and its thread blocks from pending list, and add them to * running list */ while ((grid = list_head(emu->pending_grids))) { while ((thread_block = list_head(grid->pending_thread_blocks))) { list_remove(grid->pending_thread_blocks, thread_block); list_add(grid->running_thread_blocks, thread_block); } list_remove(emu->pending_grids, grid); list_add(emu->running_grids, grid); } /* Run one instruction */ while ((grid = list_head(emu->running_grids))) { while ((thread_block = list_head(grid->running_thread_blocks))) { while ((warp = list_head(thread_block->running_warps))) { if (warp->finished || warp->at_barrier) continue; frm_warp_execute(warp); } } } /* Free finished grids */ assert(list_count(emu->pending_grids) == 0 && list_count(emu->running_grids) == 0); while ((grid = list_head(emu->finished_grids))) { /* Dump grid report */ frm_grid_dump(grid, frm_emu_report_file); /* Remove grid from finished list */ list_remove(emu->finished_grids, grid); /* Free grid */ frm_grid_free(grid); } /* Continue emulation */ return TRUE; }