免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2821 | 回复: 7
打印 上一主题 下一主题

[C] 请大神指导为什么这两个结构体的性能不一样,关于cache [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2016-07-13 15:05 |只看该作者 |倒序浏览
下面两个结构体性能不一样

#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[20];
        char buf2[20];
        char buf[cache_line_size*3];
        char buf3[20];
};

struct buf_align{
        char buf1[20];
        char buf2[20];
        char buf[cache_line_size*4];
        char buf3[20];
};

struct buf data[3];
struct buf_align data_align[3];

#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[tmp_cpu].buf1),"01234567890123456789",20);
                        memset(&(data[tmp_cpu].buf1), 0, 20);               
                        strncpy((data[tmp_cpu].buf2),"01234567890123456789",20);
                        memset(&(data[tmp_cpu].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[tmp_cpu].buf1),"01234567890123456789",20);
                        memset(&(data_align[tmp_cpu].buf1), 0, 20);               
                        strncpy((data_align[tmp_cpu].buf2),"01234567890123456789",20);
                        memset(&(data_align[tmp_cpu].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[3];
        int tmp[3];
        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] = i;
                ret=pthread_create(&tid[i],NULL,(void *) thread, &tmp[i]);
                if(ret!=0){
                        printf ("Create pthread error!\n");
                        return 1;
                }
        }

        for(i = 0; i < cpu_num; ++i)  
        {  
                pthread_join(tid[i],NULL);  
        }  

        return 0;
}
编译 gcc wlong.c -lpthread -o no
[dev:~/cache/wlong]$ ./no
size 252, align_size:316
thread0 is core0
time:672585
align time:620361

实际上两个结构体只用到了上面的buf1 和buf2 为什么后面的长度会对性能有影响?请大神指导!!!

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
2 [报告]
发表于 2016-07-13 16:09 |只看该作者
你这点估计是误差。跨多个cache line性能会慢,你只有一个线程,只用了最前面40字节,不存在此问题

论坛徽章:
0
3 [报告]
发表于 2016-07-13 16:13 |只看该作者
回复 2# hellioncu


    这个我试了很多次,如果字节对齐的话时间就会反过来,用时长的时间反而短,用时短的结构时间反而长。程序都在上面了,你也可以试试

论坛徽章:
0
4 [报告]
发表于 2016-07-13 16:13 |只看该作者
回复 2# hellioncu


    这个我试了很多次,如果字节对齐的话时间就会反过来,用时长的时间反而短,用时短的结构时间反而长。程序都在上面了,你也可以试试

论坛徽章:
324
射手座
日期:2013-08-23 12:04:38射手座
日期:2013-08-23 16:18:12未羊
日期:2013-08-30 14:33:15水瓶座
日期:2013-09-02 16:44:31摩羯座
日期:2013-09-25 09:33:52双子座
日期:2013-09-26 12:21:10金牛座
日期:2013-10-14 09:08:49申猴
日期:2013-10-16 13:09:43子鼠
日期:2013-10-17 23:23:19射手座
日期:2013-10-18 13:00:27金牛座
日期:2013-10-18 15:47:57午马
日期:2013-10-18 21:43:38
5 [报告]
发表于 2016-07-13 16:21 |只看该作者
lunixwh 发表于 2016-07-13 16:13
回复 2# hellioncu


你把
struct buf data[3];
struct buf_align data_align[3];

的先后次序换一下试试

论坛徽章:
0
6 [报告]
发表于 2016-07-13 16:35 |只看该作者
回复 5# hellioncu


    [dev:~/cache/wlong]$ ./a.out
size 92, align_size:88
thread0 is core0
time:1328583
align time:1657367

[dev:~/cache/wlong]$ ./a.out               
size 92, align_size:88
thread0 is core0
align time:1909747
time:1473750

换了一下顺序,是线程中的执行顺序

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
7 [报告]
发表于 2016-07-13 17:00 |只看该作者
本帖最后由 nswcfd 于 2016-07-13 18:08 编辑

测试了一下,调换数据的先后顺序没有影响,但是调换访问的顺序(先test align后test 非align)时间就交换了一下(先做的快,后做的慢),或者中间加入sleep(1)有时候也能把时间拉平.

或者先把数据warm一下(即插入几个memset),也能把两者的差异拉平。

PS,sleep的效果很诡异…… 难道是能等待未完成的cache同步结束?

PS2,这个效果跟buf[cache-line-size]无关,如果两个结构都只有40字节,效果没有变化。

PS3,把两个结构都对齐到64/128字节也不改变效果。

论坛徽章:
20
程序设计版块每日发帖之星
日期:2015-08-17 06:20:00程序设计版块每日发帖之星
日期:2016-07-16 06:20:00程序设计版块每日发帖之星
日期:2016-07-18 06:20:00每日论坛发贴之星
日期:2016-07-18 06:20:00黑曼巴
日期:2016-12-26 16:00:3215-16赛季CBA联赛之江苏
日期:2017-06-26 11:05:5615-16赛季CBA联赛之上海
日期:2017-07-21 18:12:5015-16赛季CBA联赛之青岛
日期:2017-09-04 17:32:0515-16赛季CBA联赛之吉林
日期:2018-03-26 10:02:16程序设计版块每日发帖之星
日期:2016-07-15 06:20:0015-16赛季CBA联赛之江苏
日期:2016-07-07 18:37:512015亚冠之萨济拖拉机
日期:2015-08-17 12:21:08
8 [报告]
发表于 2016-07-13 18:08 |只看该作者
本帖最后由 nswcfd 于 2016-07-13 20:23 编辑

有可能是gettimeofday或者printf的副作用?换成rdtscll并去掉打印,结果就一致了,先调用的时间长,后调用的时间短。

同样,预热一下数据,两者的差距就很小了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP