linux下cpu多核运行程序以及运行时间统计

news2024/9/23 15:20:53

一、多核心运行程序

在linux下我们可以指定线程或者进程运行在指定的cpu核心上,操作方法如下:

1)运行进程指定cpu核心

taskset -c 2 ./app //-c指定运行的cpu核心号,从0计数,查看效果如下:

2)运行线程指定cpu核心

主要是设置线程的属性,具体代码如下,详看main函数。

#include <stdio.h>
#include <stdlib.h>
#include <sched.h>
#include <pthread.h>
#include <time.h>

void* thread_func0(void* arg) {
    int iterations = 1000000000; // 迭代次数
    double a = 3.14159; // 乘法操作的乘数
    double b = 2.71828; // 乘法操作的被乘数
    double sum = 0.0; // 加法操作的累加器
	struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);
    // 执行乘法运算
    for (int i = 0; i < iterations; ++i) {
        double c = a * b;
        sum += c; // 将乘法结果加到累加器上
    }
    clock_gettime(CLOCK_MONOTONIC, &end);
    double time_spent = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;

    printf("cpu0 Performed %d in %f seconds\n", iterations, time_spent);
    printf("cpu0 Resulting sum: %f\n", sum);
    return NULL;
}

void* thread_func1(void* arg) {
    int iterations = 1000000000; // 迭代次数
    double a = 3.14159; // 乘法操作的乘数
    double b = 2.71828; // 乘法操作的被乘数
    double sum = 0.0; // 加法操作的累加器
	struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);
    // 执行乘法运算
    for (int i = 0; i < iterations; ++i) {
        double c = a * b;
        sum += c; // 将乘法结果加到累加器上
    }

    clock_gettime(CLOCK_MONOTONIC, &end);
    double time_spent = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;

    printf("cpu1 Performed %d in %f seconds\n", iterations, time_spent);
    printf("cpu1 Resulting sum: %f\n", sum);
    return NULL;
}

int main() {
 	pthread_t thread0, thread1; // 为每个线程使用不同的变量
    pthread_attr_t attr0, attr1; // 为每个线程属性使用不同的变量
    unsigned long mask0 = 1UL << 2; // 将线程绑定到CPU核心2
	unsigned long mask1 = 1UL << 3; // 将线程绑定到CPU核心3

	// 初始化线程属性
    pthread_attr_init(&attr0);
    pthread_attr_init(&attr1);

    pthread_attr_setaffinity_np(&attr0, sizeof(mask0), &mask0);
    pthread_create(&thread0, &attr0, thread_func0, NULL);

    pthread_attr_setaffinity_np(&attr1, sizeof(mask1), &mask1);
    pthread_create(&thread1, &attr1, thread_func1, NULL);

    // 等待线程0和线程1完成
    pthread_join(thread0, NULL);
    pthread_join(thread1, NULL);

    return 0;
}

编译后运行效果如下(代码指定了2和3,从0计数):

3)两者的优先级

代码中的线程属性设置cpu核心为2和3,进程以cpu核心0来运行,实际运行在核心2和3上。

测试代码用上述不变,运行命令为:taskset -c 0 ./app

因此,可得结论:在进程和线程都指定运行的cpu核心时,以线程为准。

二、多核心运行的时间测量需要注意的事项

1)多核计时异常

在测试运行时间时,遇到一个问题,最开始我使用的时间测试代码如下:

clock_t start = clock();//测量开始时间
//功能代码
//...
clock_t end = clock();// 测量结束时间
double time_spent = (double)(end - start) / CLOCKS_PER_SEC;

这个代码在测试单核运行的代码时,时间是对的,但是使用多核运行时,发现这个代码统计的时间是我实际手机计时的2倍,怀疑是该函数统计了本程序对所有cpu的占用时间,即双核的时间。

后修改时间测量代码如下:

struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC, &start);
//功能代码
//...
clock_gettime(CLOCK_MONOTONIC, &end);
double time_spent = (end.tv_sec - start.tv_sec) + (end.tv_nsec - start.tv_nsec) / 1e9;

测试时间和手机测试的一致。

2)clock()clock_gettime() 比较

clock()clock_gettime() 都是 C 语言标准库中用于获取时间的函数,但它们在用途和行为上有一些重要的区别:

  1. 定义和来源

    • clock() 函数定义在 <time.h> 头文件中,它测量的是程序占用 CPU 的时间(也称为 CPU 时间或处理器时间)。它返回程序启动以来的时钟周期数,这个值是通过处理器的时钟周期来计算的。
    • clock_gettime() 函数是 POSIX.1-2001 标准的一部分,也定义在 <time.h> 中,它提供了更精确的时间测量。它可以测量多种类型的时间,包括实时时间(系统时间)、进程时间、线程时间等。
  2. 时间类型

    • clock() 只能测量程序占用 CPU 的时间。
    • clock_gettime() 可以测量多种时间,通过指定不同的时钟 ID 来获取不同类型的时间。例如:
      • CLOCK_REALTIME:返回以系统实时时间为基础的时间,受系统时间的更改影响。
      • CLOCK_MONOTONIC:返回一个单调时钟,它以系统启动为基础,不受系统时间更改的影响,适合测量时间间隔。
      • CLOCK_PROCESS_CPUTIME_ID:返回调用进程占用的 CPU 时间总和。
      • CLOCK_THREAD_CPUTIME_ID:返回调用线程占用的 CPU 时间。
  3. 精度

    • clock() 的精度受限于系统和硬件,通常以秒为单位,精度较低。
    • clock_gettime() 通常提供更高的精度,可以测量到纳秒级别。
  4. 返回值

    • clock() 返回一个 clock_t 类型的值,表示程序占用 CPU 的时钟周期数。如果失败,返回 ((clock_t) -1)
    • clock_gettime() 成功时返回 0,失败时返回 -1,并设置 errno 以指示错误。
  5. 使用场景

    • clock() 适用于需要测量程序执行时间的场景,但它不适用于测量墙上时钟时间(实际时间)。
    • clock_gettime() 适用于需要高精度时间测量的场景,包括但不限于测量墙上时钟时间、系统时间、进程或线程的 CPU 时间。
  6. 多线程环境

    • 在多线程环境中,clock() 可能无法准确反映单个线程的 CPU 时间,因为它测量的是整个进程的 CPU 时间。
    • clock_gettime() 通过 CLOCK_THREAD_CPUTIME_ID 可以准确测量单个线程的 CPU 时间。
  7. 系统依赖性

    • clock() 是 C 语言标准的一部分,几乎所有的 C 语言环境都支持。
    • clock_gettime() 是 POSIX 标准的一部分,可能在非 POSIX 兼容的系统上不可用或需要特定的编译器标志。

总结来说,clock_gettime() 提供了更多的功能和更高的精度,是现代 C 语言编程中推荐的时间测量函数。而 clock() 由于其较低的精度和对多线程支持的限制,在现代编程中使用较少。

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

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

相关文章

C++map容器中operator[ ]的实现原理

目录 一、operator[ ]函数介绍 二、insert函数介绍 三、operator[ ]函数实现原理 四、operator[ ]函数功能 一、operator[ ]函数介绍 mapped_type& operator[] (const key_type& k);在map容器中存储的是一个键值对value_type&#xff0c;其本质是pair<const key…

maya python调试(pycharm)

maya里面调试代码一直用的print。遇到复杂点的类就感觉有点束手束脚的&#xff0c;因此整理了一下maya调试的一些方法 1.万能的pdb调试 pdb 有2种用法 1.非侵入式方法 &#xff08;不用额外修改源代码&#xff0c;在命令行下直接运行就能调试&#xff09; 常规用法&#xf…

APP长文本内容编辑器功能实现方案

背景 CSDN APP 中原有编辑器页面为纯H5适配&#xff0c;整体用户交互体验差&#xff0c;如何优化APP端编辑器用户体验是我们团队需要思考的问题。下面我们以iOS为例展开讨论。 一、方案调研 我们分析了几款国内内容发布的APP&#xff0c;如知乎、今日头条、简书&#xff0c;…

有了它 一键掌握Vue新版本!

声明&#xff1a;此篇为 ai123.cn 原创文章&#xff0c;转载请标明出处链接&#xff1a;https://ai123.cn/#1 你是否也在为Vue生态中的快速更新而焦头烂额&#xff1f;ue 3.4版本发布&#xff0c;带来模板解析器重写和响应系统重构&#xff0c;提升了性能和开发体验。测试框架如…

《深入理解JAVA虚拟机(第2版)》- 第3章 - 学习笔记

第3章 垃圾收集器与内存分配策略 3.1 概述 垃圾收集器要完成三件事情&#xff1a; 什么样的内存需要回收什么时候回收如何回收 垃圾收集器主要关注的区域是&#xff1a;Java堆和方法区。因为程序计数器、虚拟机栈、本地方法栈是线程私有的&#xff0c;随着线程的结束所使用的…

2d椭圆拟合学习

算法来自论文《 Direct Least Square Fitting of Ellipses》 《NUMERICALLY STABLE DIRECT LEAST SQUARES FITTING OF ELLIPSES》 相关文章 论文阅读&#xff1a;直接拟合椭圆 Direct Least Square Fitting of Ellipseshttps://zhuanlan.zhihu.com/p/645391510Fitting Elli…

rsyslog交叉编译

文章目录 1、依赖库列表2、编译建议3、编译3.1、编译libestr3.2、编译libfastjson3.3、编译zlib3.4、编译libuuid3.5、编译libgpg-error3.6、编译libgcrypt3.7、编译openssl3.8、编译curl3.9、编译rsyslog该文档描述了如何交叉编译rsyslog到arm64嵌入式平台。 1、依赖库列表 li…

UE5开发——射击武器类拾取

整体框架&#xff1a; 拾取武器 要在 Unreal Engine 5 (UE5) 中实现一个按 E 键拾取武器的功能&#xff0c;您可以遵循以下步骤&#xff1a; ### 步骤 1: 创建拾取物品的基础类 1. 在 Content Browser 中创建一个新的 C 类&#xff0c;继承自 AActor 或者 AStaticMeshActor。…

pytorch交叉熵损失函数

nn.CrossEntropyLoss 是 PyTorch 中非常常用的损失函数,特别适用于分类任务。它结合了 nn.LogSoftmax 和 nn.NLLLoss(负对数似然损失)的功能,可以直接处理未经过 softmax 的 logits 输出,计算预测值与真实标签之间的交叉熵损失。 1. 交叉熵损失的原理 交叉熵损失衡量的是…

Visual Studio Code离线汉化

从官网下载Visual Studio Code安装包后&#xff0c; 下载Visual Studio Code&#xff1a;https://code.visualstudio.com/ 若因网络等问题无法在线安装语言包&#xff0c;可以尝试离线安装&#xff1a; 从官网下载语言包&#xff1a; Extensions for Visual Studio family …

线上考试系统部署(thirty-six day)

一、线上考试系统的数据 虚拟化技术部署 1、部署前端服务器 &#xff08;1&#xff09;将资源上传到服务器 scp -r dist/ root192.168.1.11:~ &#xff08;2&#xff09;创建基础容器 在服务器上 systemctl start docker.servicedocker pull centosdocker run -it --name …

基于RAG多层次的多代理架构来处理时序任务

《Agentic Retrieval-Augmented Generation for Time Series Analysis》这篇文章提出了一种新颖的时间序列分析方法&#xff0c;称为Agentic Retrieval-Augmented Generation&#xff08;RAG&#xff09;框架。它通过多层次的多代理架构来处理时间序列任务&#xff0c;其中主代…

【银河麒麟高级服务器操作系统】soft lockup软锁实例详细记录分析及处理建议

了解更多银河麒麟操作系统全新产品&#xff0c;请点击访问 麒麟软件产品专区&#xff1a;https://product.kylinos.cn 开发者专区&#xff1a;https://developer.kylinos.cn 文档中心&#xff1a;https://documentkylinos.cn 现象描述 启nginx服务&#xff0c;但是报了sof…

WebRTC协议下的视频汇聚融合技术:EasyCVR视频技术构建高效视频交互体验

视频汇聚融合技术是指将来自不同源、不同格式、不同网络环境的视频流进行集中处理、整合和展示的技术。随着视频监控、远程会议、在线教育、直播娱乐等领域的快速发展&#xff0c;视频数据的规模急剧增长&#xff0c;对视频处理能力和效率提出了更高要求。视频汇聚融合技术通过…

海外云手机实现海外社媒矩阵营销

如何利用社交媒体平台有效推广和带货&#xff0c;正成为众多企业和创业者关注的焦点。海外云手机解决各种网络和设备问题&#xff0c;成为跨境电商海外社媒矩阵建设的必备工具。 跨境电商的核心在于通过互联网连接不同国家的消费者与商品。社交媒体作为连接消费者与品牌的桥梁&…

vue nginx部署 配置 解决href = ‘/login路由‘ 跳转404问题

示例场景 <a :hrefthis.repDownloadUrl>下载平台</a><a href"/join" target"_blank">入驻平台</a><a href"/index" target"_blank" class"btn_login" style"color:#fff">nginx部署…

Datawhale X 李宏毅苹果书 AI夏令营 Task 2

课程内容 &#xff08;一&#xff09;术语解释 一 . Sigmoid函数与Hard Sigmoid 函数 &#xff08;1&#xff09;Sigmoid函数 Sigmoid函数&#xff0c;也称为逻辑函数&#xff08;Logistic function&#xff09;&#xff0c;是一种在数学、生物学、信息科学、神经网络等领域广…

【原子提交:IDEA实践】

原子提交&#xff1a;IDEA实践 背景先前情况idea实际操作方式一&#xff1a;Squash Commits方式二&#xff1a;Undo Commit 后再 Commit方式三&#xff1a;Resetpush前操作后悔药——回到squash commit之前&#xff1a; 背景 临近发版&#xff0c;某位老哥的个线上MR包含多个b…

YOLOv8环境搭建、创建数据集、训练推理教程(超级详细)

yolov8和yolov10 是一个流派&#xff0c;和yolov5区别还挺大&#xff0c;所以尝试使用yolov8来进行模型训练&#xff0c;下面是详细使用流程&#xff1a; 一、环境搭建 1.1 Anaconda安装 Anaconda是一个强大的开源数据科学平台,它将很多好的工具整合在一起&#xff0c;极大地…

怎么在CSDN上赚钱?

CSDN平台上有多种方式可以赚钱&#xff0c;以下是其中几种常见的&#xff1a; 写作赚钱&#xff1a;CSDN平台鼓励用户积极创作原创技术博客&#xff0c;通过博客的阅读量和转发量来获取广告收益&#xff1b;用户还可以发表付费文章或参与付费专栏&#xff0c;在文章的阅读量和付…