#include <thread.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include <sys/errno.h>
#include <sys/processor.h>
#include <sys/procset.h>
#define CACHE_LINE_SIZE 32
#define DIV_NUMBER 114
#define CPU_ID_A 3
#define CPU_ID_B 4
static float* array1;
static float* array2;
int size;
int loop;
void *process_even(void* threadid);
void *process_odd(void* threadid);
void *process_lower(void* threadid);
void *process_upper(void* threadid);
void wrong_input(void);
int main (int argc, char *argv[])
{
int rc, t;
long t1,t2;
char type;
t1 = 0;
t2 = 0;
if(argc < 4)
wrong_input();
type = argv[1][0];
size = atoi(argv[2]);
loop = atoi(argv[3]);
if((type != '1')&&(type != '0')||(size <= 0)||(loop <= 0)||(size%2 != 0))
wrong_input();
/* Speicherreservierung. valloc reserviert Speicher am Block Anfang.
Mit dif wird der reservierte Speicher auf ein exaktes vielfaches der Cache-Line größe erweitert */
int dif = CACHE_LINE_SIZE-( (size*sizeof(float) )%CACHE_LINE_SIZE);
array1 = valloc(dif+size*sizeof(float));
array2 = valloc(dif+size*sizeof(float));
/* init array */
int i;
for(i = 0; i< size; i++){
array1[i] = (float)i;
array2[i] = (float)i;
}
t = 0;
pthread_t thread_even;
pthread_t thread_odd;
pthread_t thread_upper;
pthread_t thread_lower;
t1 = clock();
/* Berechnung EVEN / ODD */
if(type == '1'){
rc = pthread_create(&thread_even, NULL, process_even,(void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(1);
}
process_odd(&t);
rc = pthread_join(thread_even, NULL); /* Auf thread warten */
}
/* Berechnung UPPER / LOWER */
else if(type == '0'){
rc = pthread_create(&thread_upper, NULL, process_upper,(void *)t);
if (rc){
printf("ERROR; return code from pthread_create() is %d\n", rc);
exit(-1);
}
process_lower(&t);
rc = pthread_join(thread_upper, NULL); /* Auf thread warten */
}
t2 = clock();
if(type == '1')
printf("\nType: Even/Odd");
else
printf("\nType: Upper/Lower");
printf("\nTime: %d, size: %d, loop: %d\n\n", (t2-t1)/1000, size, loop);
pthread_exit(NULL);
}
/* Berechnen der geraden Einträge */
void *process_even(void* threadid){
/*int ret = processor_bind(P_LWPID, P_MYID, 2, NULL);
assert(ret == 0);
printf("\nCpu_id: %d", getcpuid());*/
int i, inner_l;
for(inner_l = 0; inner_l < loop; inner_l++)
for(i = 0; i < size; i = i+2)
array1[i] = (array1[i] + array2[i]) / DIV_NUMBER;
}
/* Berechnen der ungeraden Einträge */
void *process_odd(void* threadid){
/*int ret = processor_bind(P_LWPID, P_MYID, 6, NULL);
assert(ret == 0);
printf("\nCpu_id: %d", getcpuid());*/
int i, inner_l;
for(inner_l = 0; inner_l < loop; inner_l++)
for(i = 1; i < size; i = i+2)
array1[i] = (array1[i] + array2[i]) / DIV_NUMBER;
}
/* Berechnen der ersten Hälfte der arrays */
void *process_upper(void* threadid){
/*int ret = processor_bind(P_LWPID, P_MYID, 2, NULL);
assert(ret == 0);
printf("\nCpu_id: %d", getcpuid());*/
int upper_end = (size/2) -1;
int i, inner_l;
for(inner_l = 0; inner_l < loop; inner_l++)
for(i = 0; i < upper_end; i++)
array1[i] = (array1[i] + array2[i]) / DIV_NUMBER;
}
/* Berechnen der zweiten Hälfte der arrays */
void *process_lower(void* threadid){
/*int ret = processor_bind(P_LWPID, P_MYID,6, NULL);
assert(ret == 0);
printf("\nCpu_id: %d", getcpuid());*/
int lower_start = size/2;
int i, inner_l;
for(inner_l = 0; inner_l < loop; inner_l++)
for(i = lower_start; i < size; i++)
array1[i] = (array1[i] + array2[i]) / DIV_NUMBER;
}
void wrong_input(){
printf("\nWrong argument count!\n");
printf("\nArg1: type 0 = upper/lower, 1 = even/odd");
printf("\nArg2: array size (number of floats). Size modulo 2 must be 0.");
printf("\nArg3: loop count");
exit(0);
}