예제 #1
0
파일: emu.c 프로젝트: ajithcj/miaow
int SIEmuRun(Emu *self)
{
	SIEmu *emu = asSIEmu(self);

	struct si_ndrange_t *ndrange;
	struct si_wavefront_t *wavefront;
	struct si_work_group_t *work_group;

	int wavefront_id;
	long work_group_id;

	if (!list_count(emu->running_work_groups) &&
		list_count(emu->waiting_work_groups))
	{
		work_group_id = (long)list_dequeue(emu->waiting_work_groups);
		list_enqueue(emu->running_work_groups, (void*)work_group_id);
	}

	/* For efficiency when no Southern Islands emulation is selected, 
	 * exit here if the list of existing ND-Ranges is empty. */
	if (!list_count(emu->running_work_groups))
		return FALSE;

	assert(emu->ndrange);
	ndrange = emu->ndrange;

	/* Instantiate the next work-group */
	work_group_id = (long)list_bottom(emu->running_work_groups);
	work_group = si_work_group_create(work_group_id, ndrange);

//	struct si_wavefront_t* wf = work_group->wavefronts[0];
//	struct si_work_item_t* wi = wf->work_items[62];
	//printf("Vsrc1 value V0: %d\n", wi->vreg[0].as_int);
	
	/* Execute the work-group to completion */
	while (!work_group->finished_emu)
	{
		SI_FOREACH_WAVEFRONT_IN_WORK_GROUP(work_group, wavefront_id)
		{
			wavefront = work_group->wavefronts[wavefront_id];

			if (wavefront->finished || wavefront->at_barrier)
				continue;

			/* Execute instruction in wavefront */
			si_wavefront_execute(wavefront);
		}
	}
예제 #2
0
/* Run one iteration of the Southern Islands GPU emulation loop.
 * Return FALSE if there is no more emulation to perform. */
int si_emu_run(void)
{
	struct si_ndrange_t *ndrange;
	struct si_ndrange_t *ndrange_next;

	struct si_work_group_t *work_group;
	struct si_work_group_t *work_group_next;

	struct si_wavefront_t *wavefront;
	struct si_wavefront_t *wavefront_next;

	/* For efficiency when no Southern Islands emulation is selected, exit here
	 * if the list of existing ND-Ranges is empty. */
	if (!si_emu->ndrange_list_count)
		return 0;

	/* Start any ND-Range in state 'pending' */
	while ((ndrange = si_emu->pending_ndrange_list_head))
	{
		/* Set all ready work-groups to running */
		while ((work_group = ndrange->pending_list_head))
		{
			si_work_group_clear_status(work_group, si_work_group_pending);
			si_work_group_set_status(work_group, si_work_group_running);
		}

		/* Set is in state 'running' */
		si_ndrange_clear_status(ndrange, si_ndrange_pending);
		si_ndrange_set_status(ndrange, si_ndrange_running);
	}

	/* Run one instruction of each wavefront in each work-group of each
	 * ND-Range that is in status 'running'. */
	for (ndrange = si_emu->running_ndrange_list_head; ndrange; ndrange = ndrange_next)
	{
		/* Save next ND-Range in state 'running'. This is done because the state
		 * might change during the execution of the ND-Range. */
		ndrange_next = ndrange->running_ndrange_list_next;

		/* Execute an instruction from each work-group */
		for (work_group = ndrange->running_list_head; work_group; work_group = work_group_next)
		{
			/* Save next running work-group */
			work_group_next = work_group->running_list_next;

			/* Run an instruction from each wavefront */
			for (wavefront = work_group->running_list_head; wavefront; wavefront = wavefront_next)
			{
				/* Save next running wavefront */
				wavefront_next = wavefront->running_list_next;

				/* Execute instruction in wavefront */
				si_wavefront_execute(wavefront);
			}
		}
	}

	/* Free ND-Ranges that finished */
	while ((ndrange = si_emu->finished_ndrange_list_head))
	{
		/* Dump ND-Range report */
		si_ndrange_dump(ndrange, si_emu_report_file);

		/* Stop if maximum number of kernels reached */
		if (si_emu_max_kernels && si_emu->ndrange_count >= si_emu_max_kernels)
			esim_finish = esim_finish_si_max_kernels;

		/* Extract from list of finished ND-Ranges and free */
		si_ndrange_free(ndrange);
	}

	/* Return TRUE */
	return 1;
}