view tests/006_qsort/006.c @ 0:42f240cc4bc6

From: 太田 篤志 <atoc@namikilab.tuat.ac.jp>
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 08 Sep 2009 13:44:18 +0900
parents
children
line wrap: on
line source

#define _XOPEN_SOURCE 600
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/ioctl.h>
#include <sys/mman.h>
#include <memory.h>
#include <sys/time.h>
#include <pthread.h>
#include <alloca.h>

#include "../../include/ioctl.h"
#include "../../include/spe_process.h"


#define SORT 1024

typedef struct
{
	uint64_t ea;
	uint32_t count;
}
qsort_info;


typedef struct
{
	 int64_t d;
	uint64_t pad;
}
qsort_data;


volatile qsort_data data[SORT] __attribute__((aligned(16)));

volatile qsort_info info __attribute__((aligned(16)));

volatile unsigned char buffer[4096] __attribute__((aligned(128))) = { 0 };


typedef struct
{
	qsort_info info __attribute__((aligned(16)));
	spe_process_context_write_data_t spe_write;
	spe_process_context_read_data_t  spe_read;
}
myqsort_pthread;





void *my_qsort(void *arg)
{
	myqsort_pthread *pthread_arg = (myqsort_pthread *)arg;

	int fd;
	if ((fd = open("/dev/spe_manager", O_RDWR)) == -1)
	{
		printf("Can't open /dev/spe_manager.\n");
		return (void *)-1;
	}
	lseek(fd, 0, SEEK_SET);
	write(fd, &(pthread_arg->spe_write), sizeof(pthread_arg->spe_write));
	ioctl(fd, SPE_MANAGER_IOCTL_START_PROCESS);

	do
	{
		lseek(fd, 0, SEEK_SET);
		read(fd, &(pthread_arg->spe_read), sizeof(pthread_arg->spe_read));
	}
	while (pthread_arg->spe_read.status != SPE_PROCESS_CONTEXT_STATUS_NOT_RELEASED);
	close(fd);

	unsigned int ret = (unsigned int)(pthread_arg->spe_read.ret);

	if (ret > 0)
	{
		myqsort_pthread *left, *right;
		if (posix_memalign((void **)&left, 16, sizeof(myqsort_pthread)) != 0)
			return (void *)-1;
		if (posix_memalign((void **)&right, 16, sizeof(myqsort_pthread)) != 0)
			return (void *)-1;

		pthread_t p_left, p_right;

		left->info.ea             = pthread_arg->info.ea;
		left->info.count          = ret;
		left->spe_write.pgm_start = (uint64_t)buffer;
		left->spe_write.pgm_size  = 1448;
		left->spe_write.arg       = (uint64_t)&(left->info);

		pthread_create(&p_left, NULL, my_qsort, (void *)left);

		right->info.ea             = pthread_arg->info.ea + 16 * ret;
		right->info.count          = pthread_arg->info.count - ret;
		right->spe_write.pgm_start = (uint64_t)buffer;
		right->spe_write.pgm_size  = 1448;
		right->spe_write.arg       = (uint64_t)&(right->info);

		pthread_create(&p_right, NULL, my_qsort, (void *)right);


		pthread_join(p_left, NULL);
		pthread_join(p_right, NULL);
	}

	return (void *)0;
}






int main(int argc, char *argv[])
{
	int fd_mmap;
	if ((fd_mmap = open("../../spe_programs/002_qsort/spe", O_RDONLY)) == -1)
	{
		printf("Can't open spe program.\n");
		return -1;
	}
	printf("fd_mmap: %d\n", fd_mmap);

	read(fd_mmap, buffer, 1600);

	close(fd_mmap);


	printf("buffer = 0x%016lx\n", (uint64_t)buffer);
	printf("info   = 0x%016lx\n", (uint64_t)(&info));
	printf("data   = 0x%016lx\n", (uint64_t)data);


	srand(0);
	int i;
	for (i = 0; i < SORT; i++)
	{
		data[i].d = (int64_t)rand();
		printf("[%d] %ld\n", i, data[i].d);
	}


//------------------------------------------------
//	ここから時間を計測する

	struct timeval tv1, tv2, tv3;
	int fd;

	gettimeofday(&tv1, NULL);
	gettimeofday(&tv2, NULL);
/*
	spe_write.pgm_start = (uint64_t)buffer;
	spe_write.pgm_size  = 1448;
	spe_write.arg       = (uint64_t)(&info);
*/

	myqsort_pthread *root;
	if (posix_memalign((void **)&root, 16, sizeof(myqsort_pthread)) != 0)
		return -1;

	pthread_t p_root;

	root->info.ea             = (uint64_t)data;
	root->info.count          = SORT;
	root->spe_write.pgm_start = (uint64_t)buffer;
	root->spe_write.pgm_size  = 1448;
	root->spe_write.arg       = (uint64_t)&(root->info);

	pthread_create(&p_root, NULL, my_qsort, (void *)root);

	pthread_join(p_root, NULL);

//	my_qsort(0, SORT);

	gettimeofday(&tv3, NULL);

//	時間計測終了
//------------------------------------------------

	close(fd);
	printf("%lu.%06lu\n", tv1.tv_sec, tv1.tv_usec);
	printf("%lu.%06lu\n", tv2.tv_sec, tv2.tv_usec);
	printf("%lu.%06lu\n", tv3.tv_sec, tv3.tv_usec);
	fprintf(stderr, "Done.\n");

	for (i = 0; i < SORT; i++)
	{
		printf("[%d] %ld\n", i, data[i].d);
	}
//	printf("ret: %lu\n", spe_read.ret);

	return 0;
}