我有以下的任務來證明假共享,寫了一個簡單的程序:假共享和並行線程
#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;
}
當我看到結果我感到非常驚訝(我在我的酷睿i5-430M處理器,運行它)。
- 由於虛假分享,這是1020毫秒。
- 沒有虛假分享,它是710毫秒,只有30%而不是300%(它寫在一些網站上,它會比300-400%更快)。
- 沒有使用pthreads,它是580毫秒。
請給我看看我的錯誤或解釋它爲什麼會發生。
我覺得數組[0]和陣列[1]應該在一個緩存行中。他們非常接近,不是嗎? –
@AlexeyMatveev:31日和32日也非常接近。但是你認爲它們屬於不同的緩存行。事實是,他們可能也可能不在同一個緩存行上。如果1到5(以及1之前的所有值都適用)會進入一個緩存行,並且6個槽37會進入另一個緩存行? – 2011-11-30 19:27:34
@ Vlad-Lazarenko,我明白了,我也用另一個數字來測試它。 –