/* * Programa que muestra como usar procesadores distintos en threads * aqui se detecta el numero de procesadores que tienes, en mi caso es 4. * este programa crea threads que se autoasignan un procesador, los threads son creados * con un argumento el cual contiene una estructura que tendra datos a procesar distintos a cada thread * en este ejemplo procesara el promedio de los datos que se le mandan, a cada thread se le manda AAA.. , BBB.., CCC.., DDD... etc.. * o sea que cada uno en promedio debera tener 0x41,0x42,0x43,0x44, etc.. hace un loop infinito para que observes el uso de tus procesadores * * compila: * * gcc -Wall -lpth estecodigo.c -o out * * ejecutas: * * ./out * * toorandom@gmail.com * * Eduardo Ruiz Duarte (beck) * */ #define _GNU_SOURCE #include #include #include #include #include #include /* CPUs en tu maquina */ int num_cpus; /* via sysconf() con _SC_NPROCESSORS_CONF */ /* Es algo asi como el buf size de lo que se manda a cada thread para procesar */ #define TAMANO_DATOS 256 /* Esto se le pasara a cada thread, el procesador que va a utilizar, un apuntador a algo para procesar y * el tamanio de estos datos a procesar */ typedef struct contexto { long cpuid; int datos_len; void *datos; } contexto_t; /* funcion que hara un proceso paralelo obtendra datos para el thread de ctx el cual tendra datos a procesar, * cpu que se le asignara y tamanio de datos */ void * proceso_paralelo (void *ctx) { long tid; /* thread id*/ contexto_t *info; /* estructura para parsear ctx */ cpu_set_t cpuset; pthread_t thread; /* Obtenemos la estructura para poder parsear la informacion de los datos para el thread */ info = ctx; /* Sacamos la informacion que viene de main() sobre que CPUID utilizar */ tid = info->cpuid; thread = pthread_self (); CPU_ZERO (&cpuset); /* Asignamos el procesador a "este thread" que viene en la informacion del thread que pasamos de main() */ CPU_SET (tid,(cpu_set_t *) &cpuset); if(pthread_setaffinity_np (thread, sizeof (cpu_set_t), &cpuset)!=0) perror ("pthread_setaffinity_np"); /* INICIO de funcion a paralelizar, esta solo saca el promedio de los datos que se mandaron en un loop infinito * y lo imprime cada 2 millones de iteraciones */ int i,j,prom=0; /* obtenemos los datos que vienen de main para este thread, en este caso asumiremos que son "char *" */ char *data = info->datos; printf ("Empezando procesamiento en thread/cpu %ld!\n", tid); while (1) { for(i=0;idatos_len;i++) prom+=data[i]; j++; if((j%2000000) == 0) printf("Promedio de datos calculado en thread/CPU %ld fue 0x%x primer byte datos es %c\n",tid,prom/info->datos_len,data[0]); prom=0; } free(info->datos); /* NUNCA LLEGA AQUI POR SER LOOP INFINITO */ /* FIN de funcion a paralelizar */ pthread_exit (NULL); } int main (int argc, char *argv[]) { /* obtenemos primero num_cpus */ num_cpus = sysconf (_SC_NPROCESSORS_CONF); pthread_t threads[num_cpus]; /* numero de threads que haremos */ long t; /* id de thread a crear */ /* generamos estructuras, en este caso el numero de CPUs que tenemos */ contexto_t ctx[num_cpus]; memset (&ctx, 0, sizeof (ctx)); printf("El numero de procesadores que hay disponibles es %d\n",num_cpus); for (t = 0; t < num_cpus; t++) { printf ("Creando thread %ld\n", t); /* Asignamos el id de procesador t a la estructura */ ctx[t].cpuid = t; /* Metenemos A's, B's, C's, D's a threads diferentes */ ctx[t].datos = calloc (TAMANO_DATOS, sizeof (char)); memset (ctx[t].datos, 0x41 + t, TAMANO_DATOS); /* asignamos el tamanio de los datos que mandaremos al thread */ ctx[t].datos_len = TAMANO_DATOS; /* creamos el thread t-esimo y le mandamos la estructura de contexto que le corresponde */ if (pthread_create (&threads[t], NULL, proceso_paralelo,(void *)&ctx[t])!=0) { perror("pthread_create"); exit (EXIT_FAILURE); } } pthread_exit (NULL); }