J'ai la tâche suivante pour démontrer le partage faux et écrit un programme simple:faux partage et pthreads
#include <sys/times.h>
#include <time.h>
#include <stdio.h>
#include <pthread.h>
long long int tmsBegin1,tmsEnd1,tmsBegin2,tmsEnd2,tmsBegin3,tmsEnd3;
int array[100];
void *heavy_loop(void *param) {
int index = *((int*)param);
int i;
for (i = 0; i < 100000000; i++)
array[index]+=3;
}
int main(int argc, char *argv[]) {
int first_elem = 0;
int bad_elem = 1;
int good_elem = 32;
long long time1;
long long time2;
long long time3;
pthread_t thread_1;
pthread_t thread_2;
tmsBegin3 = clock();
heavy_loop((void*)&first_elem);
heavy_loop((void*)&bad_elem);
tmsEnd3 = clock();
tmsBegin1 = clock();
pthread_create(&thread_1, NULL, heavy_loop, (void*)&first_elem);
pthread_create(&thread_2, NULL, heavy_loop, (void*)&bad_elem);
pthread_join(thread_1, NULL);
pthread_join(thread_2, NULL);
tmsEnd1 = clock();
tmsBegin2 = clock();
pthread_create(&thread_1, NULL, heavy_loop, (void*)&first_elem);
pthread_create(&thread_2, NULL, heavy_loop, (void*)&good_elem);
pthread_join(thread_1, NULL);
pthread_join(thread_2, NULL);
tmsEnd2 = clock();
printf("%d %d %d\n", array[first_elem],array[bad_elem],array[good_elem]);
time1 = (tmsEnd1-tmsBegin1)*1000/CLOCKS_PER_SEC;
time2 = (tmsEnd2-tmsBegin2)*1000/CLOCKS_PER_SEC;
time3 = (tmsEnd3-tmsBegin3)*1000/CLOCKS_PER_SEC;
printf("%lld ms\n", time1);
printf("%lld ms\n", time2);
printf("%lld ms\n", time3);
return 0;
}
J'ai été très surpris quand j'ai vu les résultats (je cours sur mon processeur i5-430M).
- Avec un faux partage, il était de 1020 ms.
- Sans faux partage, il était de 710 ms, seulement 30% plus rapide au lieu de 300% (il a été écrit sur certains sites qu'il serait plus rapide que 300-400%).
- Sans utiliser de pthreads, il était de 580 ms.
S'il vous plaît montrez-moi mon erreur ou expliquer pourquoi cela arrive.
Je pense que array [0] et tableau [1] devrait être dans une ligne de cache. Ils sont très proches, n'est-ce pas? –
@AlexeyMatveev: les 31 et 32 sont très proches aussi. Mais vous supposez qu'ils appartiennent à des lignes de cache différentes. La vérité est, ils peuvent ou peuvent ne pas être sur la même ligne de cache. Que faire si 1 à 5 (et tout avant 1, ça va) va à une ligne de cache et 6 creux 37 va à un autre? –
@ Vlad-Lazarenko, je le comprends, j'ai testé cela avec d'autres chiffres, aussi. –