/* My first pthread routine to test the local and remote memory access time difference of AMD and Intel CPU*/
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <sched.h>
#include <pthread.h>
#include <errno.h>
#define handle_error_en(en, msg) \
do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
#define MEM_SIZE 1024*1024*1024
#define NUM 10
cpu_set_t cpu_info;
pthread_barrier_t barrier;
pthread_barrier_t barrier1;
int *b;
void *thread()
{
int s,i,j;
pthread_t myid = pthread_self();
CPU_ZERO(&cpu_info);
CPU_SET(1, &cpu_info);
s = pthread_setaffinity_np( myid , sizeof(cpu_set_t), &cpu_info);
/*if(ret_v != 0){printf("New thread set failed\n"); exit(1);}
ret_v = sched_getaffinity( myid , sizeof(cpu_set_t), &cpu_info_get);
if(ret_v != 0){printf("Main thread get failed\n"); exit(1);}
for(i=0; i<sizeof(cpu_set_t); i++)
printf("%d", cpu_info_get.__bits[i]);*/
if (s != 0)
handle_error_en(s, "pthread_setaffinity_np");
/* Check the actual affinity mask assigned to the thread */
s = pthread_getaffinity_np(myid, sizeof(cpu_set_t), &cpu_info);
if (s != 0)
handle_error_en(s, "pthread_getaffinity_np");
printf("Set returned by pthread_getaffinity_np() contained:\n");
for (j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, &cpu_info))
printf(" CPU %d\n", j);
printf("\nHello! New thread!\n");
//pthread_barrier_wait(&barrier);
b = (int*)malloc(sizeof(int) * MEM_SIZE);
if(b == NULL) {printf("Malloc failed!\n"); exit(1);}
for(i=0; i<MEM_SIZE; i++)
b[i]= 0;
printf("malloc and touch b finished!\n");
pthread_barrier_wait(&barrier);
pthread_barrier_wait(&barrier1);
free(b);
pthread_exit( (void*)1 );
}
int main()
{
pthread_t pt;
int s,ret_v,i,j;
pthread_t myid = pthread_self();
pthread_barrier_init (&barrier, NULL, 2);
pthread_barrier_init (&barrier1, NULL, 2);
printf("Staring main....\n");
CPU_ZERO(&cpu_info);
CPU_SET(0, &cpu_info);
/*
ret_v = sched_setaffinity(0, sizeof(cpu_set_t), &cpu_info);
if(ret_v != 0){printf("Main thread set failed\n"); exit(1);}
ret_v = sched_getaffinity(0 , sizeof(cpu_set_t), &cpu_info);
if(ret_v != 0){printf("Main thread get failed\n"); exit(1);}
for(i=0; i<sizeof(cpu_set_t); i++)
printf("%d", cpu_info.__bits[i]);
putchar('\n');*/
s = pthread_setaffinity_np( myid , sizeof(cpu_set_t), &cpu_info);
if (s != 0)
handle_error_en(s, "pthread_setaffinity_np");
/* Check the actual affinity mask assigned to the thread */
s = pthread_getaffinity_np(myid, sizeof(cpu_set_t), &cpu_info);
if (s != 0)
handle_error_en(s, "pthread_getaffinity_np");
printf("Set returned by pthread_getaffinity_np() contained:\n");
for (j = 0; j < CPU_SETSIZE; j++)
if (CPU_ISSET(j, &cpu_info))
printf("Main thread on CPU %d\n", j);
int *a = (int*)malloc(sizeof(int)*MEM_SIZE);
if(a == NULL) printf("Malloc failed!\n");
double timeuse=0.0;
for(i=0; i<MEM_SIZE; i++)
a[i]=0;
printf("Memory a touched!\n");
ret_v = pthread_create(&pt,NULL,thread,NULL);
if(ret_v !=0 ){printf("Thread creat error!"); exit(1);}
printf("New thread created!\n");
/*CPU_ZERO(&cpu_info);
CPU_SET(1, &cpu_info);
ret_v = sched_setaffinity( pt, sizeof(cpu_set_t), &cpu_info);
printf("New thread set!\n");*/
pthread_barrier_wait(&barrier);
printf("######################\n");
struct timeval start;
struct timeval end;
srand(6);
gettimeofday(&start, NULL);
for(j=0; j<NUM; j++)
for(i=0; i<MEM_SIZE; i++)
a[i]=j;
gettimeofday(&end, NULL);
timeuse = 1e6*(end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
printf("Local Memory time %lf us \n",(timeuse/NUM));
printf("######################\n");
srand(6);
gettimeofday(&start, NULL);
for(j=0; j<NUM; j++)
for(i=0; i<MEM_SIZE; i++)
b[i]=j;
gettimeofday(&end, NULL);
timeuse = 1e6*(end.tv_sec - start.tv_sec) + end.tv_usec - start.tv_usec;
printf("Remote Memory time %lf us \n",(timeuse/NUM));
pthread_barrier_wait(&barrier1);
pthread_barrier_destroy(&barrier);
pthread_barrier_destroy(&barrier1);
free(a);
return 0;
}