下面是测试代码:两个线程分别计算5亿次累加两个相邻变量的时间消耗。
//test_false_sharing_1.cpp
#include <stdio.h>
#include <sys/time.h>
#include <time.h>
#include <pthread.h>
#define PACK __attribute__ ((packed))
typedef int cache_line_int __attribute__((aligned(LEVEL1_DCACHE_LINESIZE)));
struct data
{
int a;
int b;
};
#define MAX_NUM 500000000
void* thread_func_1(void* param)
{
timeval start, end;
gettimeofday(&start, NULL);
data* d = (data*)param;
for (int i=0; i<MAX_NUM; ++i)
{
++d->a;
}
gettimeofday(&end, NULL);
printf("thread 1, time=%d\n", (int)(end.tv_sec-start.tv_sec)*1000000+(int)(end.tv_usec-start.tv_usec));
return NULL;
}
void* thread_func_2(void* param)
{
timeval start, end;
gettimeofday(&start, NULL);
data* d = (data*)param;
for (int i=0; i<MAX_NUM; ++i)
{
++d->b;
}
gettimeofday(&end, NULL);
printf("thread 2, time=%d\n", (int)(end.tv_sec-start.tv_sec)*1000000+(int)(end.tv_usec-start.tv_usec));
return NULL;
}
int main()
{
data d = {a:0, b:0};
pthread_t t1, t2;
pthread_create(&t1, NULL, thread_func_1, &d);
pthread_create(&t2, NULL, thread_func_2, &d);
pthread_join(t1, NULL);
pthread_join(t2, NULL);
printf("end, a=%d,b=%d\n", d.a, d.b);
return 0;
}
/*
g++ -o test_false_sharing_1 test_false_sharing_1.cpp -g -Wall -O2
*/
----------------------------------------------
执行后输出:
thread 1, time=4121562
thread 2, time=4329193
thread 2, time=4329193
把以上程序稍稍修改:
struct data
{
cache_line_int a;
cache_line_int b;
};
//struct中的int修改为按照cache_line对齐的int
然后酱紫编译:
g++ -o test_false_sharing_2 test_false_sharing_2.cpp -g -Wall -lpthread -DLEVEL1_DCACHE_LINESIZE=`getconf LEVEL1_DCACHE_LINESIZE`
执行后输出:
thread 1, time=1607430
thread 2, time=1629508
thread 2, time=1629508
性能提高了2.5倍。
-------------------------------------------------
测试中注意两点:
1. int重新对齐的定义后,在struct中不要在定义对齐的属性,否则之前的对齐属性会失效;
2. 采用getconf LEVEL1_DCACHE_LINESIZE这样的命令获得cache line的大小;
3. 编译中不能加上-O2,否则编译器计算会导致瞬间出结果;(这个优化真是强大啊)
3. 编译中不能加上-O2,否则编译器计算会导致瞬间出结果;(这个优化真是强大啊)
没有评论:
发表评论