请大神指导为什么这两个结构体的性能不一样,关于cache
下面两个结构体性能不一样#define _GNU_SOURCE /* See feature_test_macros(7) */
#include <sched.h>
#include <stdio.h>
#include <string.h>
#include <pthread.h>
#include <sys/time.h>
#include <stdlib.h>
#include <unistd.h>
#include <stdint.h>
#ifndef __aligned
#define __aligned(x) __attribute__((aligned(x)))
#endif
#define cache_line_size 64
这两个结构体性能不一样
struct buf{
char buf1;
char buf2;
char buf;
char buf3;
};
struct buf_align{
char buf1;
char buf2;
char buf;
char buf3;
};
struct buf data;
struct buf_align data_align;
#define time 100000000
void thread(void *cpu)
{
int i = 0;
struct timeval tv_begin, tv_end;
cpu_set_t mask;
CPU_ZERO(&mask);
int tmp_cpu = *(int *)cpu;
CPU_SET(tmp_cpu, &mask);
if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0) {
printf("set thread affinity failed\n");
}
cpu_set_t get;
CPU_ZERO(&get);
if (pthread_getaffinity_np(pthread_self(), sizeof(get), &get) < 0) {
printf("get thread affinity failed\n");
}else{
int j;
for(j = 0; j < 4; j++){
if(CPU_ISSET(j, &get)) {
printf("thread%d is core%d\n",*(int *)cpu, j);
}
}
}
gettimeofday(&tv_begin, NULL);
for(i = 0; i < time; i++){
strncpy((data.buf1),"01234567890123456789",20);
memset(&(data.buf1), 0, 20);
strncpy((data.buf2),"01234567890123456789",20);
memset(&(data.buf2), 0, 20);
}
gettimeofday(&tv_end, NULL);
printf("time:%d\n", (tv_end.tv_sec - tv_begin.tv_sec)*1000000 + (tv_end.tv_usec - tv_begin.tv_usec));
/*align*/
gettimeofday(&tv_begin, NULL);
for(i = 0; i < time; i++){
strncpy((data_align.buf1),"01234567890123456789",20);
memset(&(data_align.buf1), 0, 20);
strncpy((data_align.buf2),"01234567890123456789",20);
memset(&(data_align.buf2), 0, 20);
}
gettimeofday(&tv_end, NULL);
printf("align time:%d\n", (tv_end.tv_sec - tv_begin.tv_sec)*1000000 + (tv_end.tv_usec - tv_begin.tv_usec));
}
int cpu_num = 1;
int main(void)
{
pthread_t tid;
int tmp;
int i,ret;
memset(&data, 0, sizeof(struct buf)*3);
printf("size %d, align_size:%d\n",sizeof(struct buf),sizeof(struct buf_align));
for(i = 0; i < cpu_num; i++){
tmp = i;
ret=pthread_create(&tid,NULL,(void *) thread, &tmp);
if(ret!=0){
printf ("Create pthread error!\n");
return 1;
}
}
for(i = 0; i < cpu_num; ++i)
{
pthread_join(tid,NULL);
}
return 0;
}
编译 gcc wlong.c -lpthread -o no
$ ./no
size 252, align_size:316
thread0 is core0
time:672585
align time:620361
实际上两个结构体只用到了上面的buf1 和buf2 为什么后面的长度会对性能有影响?请大神指导!!!
你这点估计是误差。跨多个cache line性能会慢,你只有一个线程,只用了最前面40字节,不存在此问题 回复 2# hellioncu
这个我试了很多次,如果字节对齐的话时间就会反过来,用时长的时间反而短,用时短的结构时间反而长。程序都在上面了,你也可以试试 回复 2# hellioncu
这个我试了很多次,如果字节对齐的话时间就会反过来,用时长的时间反而短,用时短的结构时间反而长。程序都在上面了,你也可以试试 lunixwh 发表于 2016-07-13 16:13 static/image/common/back.gif
回复 2# hellioncu
你把
struct buf data;
struct buf_align data_align;
的先后次序换一下试试 回复 5# hellioncu
$ ./a.out
size 92, align_size:88
thread0 is core0
time:1328583
align time:1657367
$ ./a.out
size 92, align_size:88
thread0 is core0
align time:1909747
time:1473750
换了一下顺序,是线程中的执行顺序 本帖最后由 nswcfd 于 2016-07-13 18:08 编辑
测试了一下,调换数据的先后顺序没有影响,但是调换访问的顺序(先test align后test 非align)时间就交换了一下(先做的快,后做的慢),或者中间加入sleep(1)有时候也能把时间拉平.
或者先把数据warm一下(即插入几个memset),也能把两者的差异拉平。
PS,sleep的效果很诡异…… 难道是能等待未完成的cache同步结束?
PS2,这个效果跟buf无关,如果两个结构都只有40字节,效果没有变化。
PS3,把两个结构都对齐到64/128字节也不改变效果。 本帖最后由 nswcfd 于 2016-07-13 20:23 编辑
有可能是gettimeofday或者printf的副作用?换成rdtscll并去掉打印,结果就一致了,先调用的时间长,后调用的时间短。
同样,预热一下数据,两者的差距就很小了。
页:
[1]