J'ai créé ce petit programme pour calculer pi en utilisant la probabilité et les ratios. Afin de le faire tourner plus vite, j'ai décidé de donner un multithreading avec pthreads. Malheureusement, même après avoir fait beaucoup de recherches, je n'ai pas pu résoudre le problème que j'ai quand j'exécute la fonction threadFunc, avec un thread, que ce soit avec un pthread, ou normalement appelé depuis la fonction calculate_pi_mt, la performance est beaucoup mieux (au moins deux fois ou même trois fois mieux) que lorsque j'essaie de l'utiliser avec deux threads sur ma machine dual core. J'ai essayé de désactiver les optimisations en vain. Pour autant que je puisse voir, quand le thread est en cours d'exécution, il utilise des variables locales à la fin quand j'ai utilisé un verrou mutex pour créer la somme des hits ...C: problèmes de performances pthread. Comment puis-je faire ce code comme prévu?
D'abord, y a-t-il des astuces pour créer du code? cela fonctionnera mieux ici? (style) parce que je suis en train d'apprendre en essayant ce genre de choses.
Et d'autre part, y aurait-il une raison à ces problèmes de performance évidents? Lorsque le nombre de threads est défini sur 1, l'un de mes processeurs atteint 100%. Quand il est réglé à deux, le deuxième cpu s'élève à environ 80% -90%, mais tout ce travail supplémentaire est apparemment inutile! Serait-ce l'utilisation de la fonction rand()?
struct arguments {
int n_threads;
int rays;
int hits_in;
pthread_mutex_t *mutex;
};
void *threadFunc(void *arg)
{
struct arguments* args=(struct arguments*)arg;
int n = 0;
int local_hits_in = 0;
double x;
double y;
double r;
while (n < args->rays)
{
n++;
x = ((double)rand())/((double)RAND_MAX);
y = ((double)rand())/((double)RAND_MAX);
r = (double)sqrt(pow(x, 2) + pow(y, 2));
if (r < 1.0){
local_hits_in++;
}
}
pthread_mutex_lock(args->mutex);
args->hits_in += local_hits_in;
pthread_mutex_unlock(args->mutex);
return NULL;
}
double calculate_pi_mt(int rays, int threads){
double answer;
int c;
unsigned int iseed = (unsigned int)time(NULL);
srand(iseed);
if ((float)(rays/threads) != ((float)rays)/((float)threads)){
printf("Error: number of rays is not evenly divisible by threads\n");
}
/* argument initialization */
struct arguments* args = malloc(sizeof(struct arguments));
args->hits_in = 0;
args->rays = rays/threads;
args->n_threads = 0;
args->mutex = malloc(sizeof(pthread_mutex_t));
if (pthread_mutex_init(args->mutex, NULL)){
printf("Error creating mutex!\n");
}
pthread_t thread_ary[MAXTHREADS];
c=0;
while (c < threads){
args->n_threads += 1;
if (pthread_create(&(thread_ary[c]),NULL,threadFunc, args)){
printf("Error when creating thread\n");
}
printf("Created Thread: %d\n", args->n_threads);
c+=1;
}
c=0;
while (c < threads){
printf("main waiting for thread %d to terminate...\n", c+1);
if (pthread_join(thread_ary[c],NULL)){
printf("Error while waiting for thread to join\n");
}
printf("Destroyed Thread: %d\n", c+1);
c+=1;
}
printf("Hits in %d\n", args->hits_in);
printf("Rays: %d\n", rays);
answer = 4.0 * (double)(args->hits_in)/(double)(rays);
//freeing everything!
pthread_mutex_destroy(args->mutex);
free(args->mutex);
free(args);
return answer;
}
Optimisation prématurée. Remplacer le pow inutile (x, 2) + pow (y, 2) 'par' (x * x + y * y) 'et supprimer le' sqrt' inutile (indice: un nombre positif est inférieur ou égal à 1 si et seulement si sa racine carrée est inférieure ou égale à 1) devrait vous donner plusieurs fois le bénéfice que les threads pourraient donner. –