Jouons avec quelques notions de base…
Matthieu Arzel & Serge Guelton
#include <pthread.h> void* task(void* arg) { ... } ... pthread_t thread int value; pthread_create(&thread, NULL, task, &value); void* ret; pthread_join(thread, &ret);
for(int i = 0; i < n; ++i) task();
for(int i = 0; i < n; ++i) task(i);
const struct state s; for(int i = 0; i < n; ++i) task(&s, i);
struct state s; for(int i = 0; i < n; ++i) task(&s, i);
Examinez le fichier parallel_for.c.
> gcc -O2 parallel_for.c -o parallel_for > parallel_for 10 elapsed time: 487.425000 ms
Parallélisez à l'aide de <pthread.h> et
int acc = 0; for(int i = 0; i < n; ++i) acc += i * i;
int acc = 0; for(int i = 0; i < n; ++i) acc = reduce(acc, i * i);
int acc = 0; for(int i = 0; i < n; ++i) acc = reduce(acc, task(i));
Inspectez le programme reduce.c (C11 !)
> gcc reduce.c -o reduce > ./reduce 100000 2 elapsed time: 4.300000 ms result: 5000050000
struct stack work; void produce() { while(true) stack_push(&work, random()); } void consume() { while(true) task(stack_pop(&work)); }
Comment garantire l'atomicité des opérations ?
Examinez le fichier consumer_worker.c.
> gcc -O2 consumer_worker.c -o consumer_worker > ./consumer_worker | head -n 10 pushed: 0 read: 0 pushed: 1 read: 1 pushed: 2 read: 2 pushed: 3 read: 3 pushed: 4 read: 3
Rendre la structure de donnée thread-safe à l'aide de
puis à l'aide <stdatomic.h> et