C/C++性能提升之cache分析

news2024/11/24 10:25:45

        在开发过程中,我们有时会碰到程序性能瓶颈,这时候需要我们查找热点代码,借用一些命令、工具去分析自己的程序,下面我就介绍一下如何使用perf工具分析程序的cache命中率。

        在编写代码前先介绍一下我们的硬件平台,我电脑的CPU 是酷睿i7-12700h (14个核20线程),系统ubuntu22.04, 内存16G,大概信息如下:

 

 接下来上我们的代码:

//
// Created by rookie on 23-6-4.
//
#define _GNU_SOURCE             /* See feature_test_macros(7) */
#include <sched.h>
#include <pthread.h>
#include <stdlib.h>
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <sys/syscall.h>   /* For SYS_xxx definitions */


#if  0
struct multi_var
{
    volatile int threadAVar;
    volatile int threadBVar;
}g_multi_var __attribute__((aligned(64)));
#else
struct multi_var
{
    volatile int threadAVar __attribute__((aligned(64)));
    volatile int threadBVar __attribute__((aligned(64)));
}g_multi_var;
#endif

static const char *usage_str = "test cache\r\n";
static void usage()
{
    printf("%s", usage_str);
}

void test_cpu_performance(unsigned  int cpu)
{
    float f1 = 1.2;
    double db1 = 2.3;
    int i;
    int count = 0;
    int n = 0, n1 = 0;
    double d = 1;
    struct timeval a1, a2;
    gettimeofday(&a1, NULL);
    if(cpu == 0){
        count = 0;
        while (count++ <= 100){
            for (n = 1; n < 1024*1024; ++n) {
                g_multi_var.threadAVar += n;
            }
        }
    } else if(cpu == 1){
        count = 0;
        while (count++ <= 100){
            for (n = 1; n < 1024*1024; ++n) {
                g_multi_var.threadBVar += n;
            }
        }
    }
    gettimeofday(&a2, NULL);
    long time = 1000000*(a2.tv_sec-a1.tv_sec)+a2.tv_usec-a1.tv_usec;
    printf("cpu = %d,time = %ld exit\r\n", cpu, time);
}

static int set_cpu_affinity(unsigned int cpu)
{
    cpu_set_t cpuset;
    pid_t tid = syscall(SYS_gettid);
    CPU_ZERO(&cpuset);
    CPU_SET(cpu, &cpuset);
    printf("before sched setaffinity cpu=%d\r\n", cpu);
    if(sched_setaffinity(tid, sizeof(cpuset), &cpuset) < 0){
        perror("sched setaffinity");
        printf("cpu %d\r\n", cpu);
        return -1;
    }
    printf("pid = %d, after sched setaffinity cpu=%d\r\n", tid, cpu);
    return 0;
}
static void* wast_cpu_body(void* arg)
{
    int i = 2;
    unsigned  int cpu = *(unsigned int *)arg;
    printf("wast_cpu_body in cpu=%d\r\n", cpu);
    set_cpu_affinity(cpu);
    test_cpu_performance(cpu);
    return NULL;
}

int main(int argc, char* argv[])
{
    pthread_t *thread;
    int cpunum = 4;
    int ret = 0;
    int j = 0;
    int *icpu = NULL;
    pthread_attr_t *attr = NULL;
    void *p_arg = NULL;

    if(argc > 2){
        usage();
    }else if(argc == 2){
        cpunum = atoi(argv[1]);
        thread = malloc(sizeof(*thread) * cpunum);
        attr = malloc(sizeof(*attr) * cpunum);
        icpu = malloc(sizeof(*icpu) * cpunum);
        for (j = 0; j < cpunum; ++j) {
            ret = pthread_attr_init(&attr[j]);
//        ret |= pthread_attr_setdetachstate(&attr[j], PTHREAD_CREATE_DETACHED);
            icpu[j] = j;
            ret |= pthread_create(&thread[j], &attr[j], (void*(*)(void*))wast_cpu_body, &icpu[j]);
            printf("cpu index = %d\r\n", j);
        }
        for (j = 0; j < cpunum; ++j) {
            pthread_join(thread[j], NULL);
        }
        for (j = 0; j < cpunum; ++j) {
            pthread_attr_destroy(&attr[j]);
        }
        free(icpu);
        free(thread);
        free(attr);
    }

    return ret;
}

这里说明一下,关于代码中的__attribute__((aligned(64)))  对齐字节数为什么选择64?

这是由于我电脑的CPU的CACHE_LINE就是64,具体可以使用getconf命令查看

接下来我们编译出来两个可执行文件,test_cache0test_cache1,与上述条件判断的对应关系如下: 

//test_cache1 !!!!
struct multi_var
{
    volatile int threadAVar;
    volatile int threadBVar;
}g_multi_var __attribute__((aligned(64)));

//test_cache0 !!!!
struct multi_var
{
    volatile int threadAVar __attribute__((aligned(64)));
    volatile int threadBVar __attribute__((aligned(64)));
}g_multi_var;

 然后我们使用perf检测它们执行的情况

sudo perf stat -e L1-dcache-load-misses,L1-icache-load-misses,L1-dcache-load,L1-dcache-stores,branch-load-miss,branch-loads  ./test_cache0 10

sudo perf stat -e L1-dcache-load-misses,L1-icache-load-misses,L1-dcache-load,L1-dcache-stores,branch-load-miss,branch-loads  ./test_cache1 10

通过上述信息我们发现0方式比 1方式运行的时间少了几乎50%

0方式的 cpu_core/L1-dcache-load-misses/  是36,246 , cpu_core/L1-dcache-load/ 是848,148,941,命中率为0.999957265

1方式的 cpu_core/L1-dcache-load-misses/  是38,540 , cpu_core/L1-dcache-load/ 是848,192,764,命中率为0.999954562

所以我们写代码时应该多注意对齐、以及cache这些问题,感兴趣的同学还可以多试试不以64对齐的情况

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/610099.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【LeetCode全题库算法速练】2、两数相加

文章目录 一、题目&#x1f538;题目描述&#x1f538;样例1&#x1f538;样例2&#x1f538;样例3 二、代码参考 作者&#xff1a;KJ.JK &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &#x1f308; &a…

chatgpt赋能python:Python多行代码一行展示:精简代码,高效编程的绝佳选择

Python多行代码一行展示&#xff1a;精简代码&#xff0c;高效编程的绝佳选择 介绍 在Python的开发中&#xff0c;我们经常需要编写较长的代码&#xff0c;在展示和调试代码时&#xff0c;多行代码会使代码显得过长和复杂。同时&#xff0c;多行代码还会增加代码中的空白行数…

chatgpt赋能python:Python处理颜色RGB简介

Python 处理颜色 RGB 简介 在现代 Web 设计中&#xff0c;颜色的使用非常重要。网站和应用程序的设计师通常需要控制经他们的项目中使用的颜色。最常见的颜色表示方法是 RGB&#xff0c;即红、绿、蓝。RGB 是一种添加光线颜色的方法&#xff0c;它基于红、绿和蓝三种颜色原料的…

Linux操作系统——第一章 进程

目录 基本概念 描述进程-PCB task_struct-PCB的一种 task_ struct内容分类 组织进程 查看进程 通过系统调用获取进程标示符 通过系统调用创建进程-fork初识 进程状态 进程状态查看 Z(zombie)-僵尸进程 僵尸进程危害 孤儿进程 进程优先级 基本概念 查看系统进程 …

【RestAPI】优秀Rest API设计规范

一、API 设计原则 将 REST 映射到 DDD 模式 实体、聚合和值对象等模式旨在对领域模型中的对象施加特定的约束。 在 DDD 的许多介绍文章中&#xff0c;模式是使用构造函数或属性 getter 和 setter 等面向对象的 (OO) 语言概念建模的。 设计 API 时&#xff0c;请考虑这些 API…

前后端分离的前端部署渲染方案总结

前后端分离主要是为了区分后端和前端&#xff0c;以前前端代码是直接将HTML和静态文件丢给后端&#xff0c;由后端完成数据动态交互&#xff0c;所以后端既要写后端逻辑&#xff0c;又要写前端的数据交互逻辑。 前后端分离后后端只需要提供接口&#xff0c;前端则必须要完成对…

安装lora+启动lora+训练一个model

一、安装步骤 conda create -n kohya_ss python3.10.8 cd code git clone https://github.com/bmaltais/kohya_ss.git cd kohya_ss 然后修改了setup.sh里面的xformers里面的下载地址&#xff08;因为自带的那个地址&#xff0c;拉取需要1个小时&#xff0c;太慢了&#xff09;…

chatgpt赋能python:Python基础词汇解析

Python基础词汇解析 作为一门流行且易学的编程语言&#xff0c;Python在很多场合得到了广泛的应用。在学习Python编程的过程中&#xff0c;掌握各类基础词汇是非常关键的。本文将介绍Python编程中一些常见且重要的基础词汇&#xff0c;帮助大家更好地了解和掌握Python编程。 …

chatgpt赋能python:Python多级雷达图绘制解析

Python多级雷达图绘制解析 雷达图&#xff08;Radar Chart&#xff09;是一种可视化工具&#xff0c;常用于多个指标的对比展示。与其他图形不同&#xff0c;雷达图中&#xff0c;数据不是放在X、Y轴上&#xff0c;而是以多边形的形式展现。利用Python语言&#xff0c;可以绘制…

chatgpt赋能python:Python声音检测:如何用Python实现声音检测

Python声音检测&#xff1a;如何用Python实现声音检测 声音检测是近年来越来越受到关注的技术&#xff0c;它可以应用在很多场合&#xff0c;如语音识别、安防监控等。Python作为一种强大的编程语言&#xff0c;也可以实现声音检测功能。本文将介绍Python声音检测的原理、实现…

chatgpt赋能python:Python多选:提升代码效率的必备工具

Python 多选&#xff1a;提升代码效率的必备工具 如果你是一个有多年 Python 编程经验的工程师&#xff0c;那么你肯定会知道 Python 多选是一个非常实用的工具。它可以帮助你提高代码的效率&#xff0c;减少编程的时间和工作量。在本文中&#xff0c;我们将介绍 Python 多选的…

模拟实现 Spring IOC(详解)

文章目录 前言Spring IoCSpring IoC 概述Spring IoC 技术难点Spring IoC 框架思考需求分析 Spring IoC 技术难点实现Spring IoC 模拟实现Bean工厂模式实现Bean注解的循环依赖基础建立 前言 Spring是一种 Java 开发框架&#xff0c;其主要功能有两个&#xff1a;IoC(DI)和AOP。…

什么是高并发?

目录 什么是高井发系统 1.1 什么是高井发 1.2 高井发系统有哪些关键指标 1.2.1 响应时间 1.2.2 吞吐量 1.2.3 每秒请求数(QPS) 1.2.4 每秒事务数 (TPS) 1.2.5 访问量 (PV) 1.2.6 独立访客 (UV) 1.2.7 网络流量 1.3 为什么学习高并发系统 1.32在面试中脱颖而出 什么…

Android:Selector + Layer-lists + Shape 实现 “缺右下角Button“

UI需求&#xff1a;实现"缺右下角的渐变Button"效果 实现方式有两种&#xff1a; 一.UI绘制.9背景图&#xff0c;Selector直接实现 二.使用Shape与Selector、Layer-lists实现 UI给的设计稿里没有Button背景图&#xff0c;我用Shape做完了他告诉我他有做背景图&…

字符串搜索算法:暴力搜索,KMP

目录 前言废话暴力搜索KMP算法 前言废话 最近脑子有点昏昏沉沉&#xff0c;喝点那种红枣泡的白酒居然神奇的好了一些&#xff0c;感觉很舒服。看来喝少量的酒可以让人更清醒&#xff0c;长期喝可能有养生的效果&#xff1f; 写道这里去百度了下&#xff0c;发现红枣还真有养生效…

js中this关键字的作用和如何改变其上下文

一、this 关键字的作用 JavaScript 中的 this 关键字引用了所在函数正在被调用时的对象。在不同的上下文中&#xff0c;this 的指向会发生变化。 在全局上下文中&#xff0c;this 指向全局对象&#xff08;在浏览器中是 window 对象&#xff0c;在 Node.js 中是 global 对象&…

CV | Emotionally Enhanced Talking Face Generation论文详解及代码实现

本博客主要讲解了Emotionally Enhanced Talking Face Generation&#xff08;情感增强的谈话人脸生成&#xff09;论文概括与项目实现&#xff0c;以及代码理解。 Emotionally Enhanced Talking Face Generation Paper :https://arxiv.org/pdf/2303.11548.pdf Code: GitHub - s…

ROS:服务数据(srv)的定义与使用

目录 一、服务模型二、创建功能包三、自定义服务数据3.1定义srv文件3.2在package.xml中添加功能包依赖3.3在CMakeLists.txt中添加编译选项3.4编译生成语言相关文件 四、创建代码并编译运行&#xff08;C&#xff09;4.1创建代码4.2编译4.3运行 一、服务模型 Client发布显示某个…

价值8800元SEO自动化养权重流量站课程分享(升级版)!

本来想做培训收8800&#xff0c;但是我怕大伙骂我&#xff08;说我割韭菜&#xff09;&#xff0c;所以我决定免费把这套自动化批量养站的技术和流程详细给大家分享出来。有些朋友可能是手动养&#xff0c;我觉得这种思路是没错的&#xff0c;但是有点鸡肋&#xff0c;先说下缺…

电子科技大学计算机系统结构复习笔记(三):流水线技术

目录 前言 重点一览 流水线定义 基本概念 流水线分类 流水线特点 流水线时空图 流水线性能分析 流水线特点 经典5段流水线RISC处理器 流水线的三种冒险 冒险分类 停顿流水线 结构冒险 数据冒险 控制冒险 流水线处理机的指令系统 流水线指令系统与格式 流水…