首页 > 其他分享 >文盘Rust -- tokio绑定cpu实践

文盘Rust -- tokio绑定cpu实践

时间:2023-06-05 12:33:41浏览次数:55  
标签:core -- sum ids 文盘 let tokio println

tokio 是 rust 生态中流行的异步运行时框架。在实际生产中我们如果希望 tokio 应用程序与特定的 cpu core 绑定该怎么处理呢?这次我们来聊聊这个话题。

首先我们先写一段简单的多任务程序。

use tokio::runtime;
pub fn main() {
    let rt = runtime::Builder::new_multi_thread()
        .enable_all()
        .build()
        .unwrap();

    rt.block_on(async {
        for i in 0..8 {
            println!("num {}", i);
            tokio::spawn(async move {
                loop {
                    let mut sum: i32 = 0;
                    for i in 0..100000000 {
                        sum = sum.overflowing_add(i).0;
                    }
                    println!("sum {}", sum);
                }
            });
        }
    });
}

程序非常简单,首先构造一个tokio runtime 环境,然后派生多个 tokio 并发,每个并发执行一个无限循环做overflowing_add。overflowing_add函数返回一个加法的元组以及一个表示是否会发生算术溢出的布尔值。如果会发生溢出,那么将返回包装好的值。然后取元祖的第一个元素打印。

这个程序运行在 Ubuntu 20 OS,4 core cpu。通过nmon的监控如下:

tokio_cpu_affinity_01

可以看到每个 core 都有负载。

要想把负载绑定在某一 core 上,需要使用core_affinity_rs。core_affinity_rs是一个用于管理CPU亲和力的Rust crate。目前支持Linux、Mac OSX和Windows。官方宣称支持多平台,本人只做了linux 操作系统的测试。

我们把代码修改一下:

use tokio::runtime;

pub fn main() {
    let core_ids = core_affinity::get_core_ids().unwrap();
    println!("core num {}", core_ids.len());
    let core_id = core_ids[1];

    let rt = runtime::Builder::new_multi_thread()
        .on_thread_start(move || {
            core_affinity::set_for_current(core_id.clone());
        })
        .enable_all()
        .build()
        .unwrap();

    rt.block_on(async {
        for i in 0..8 {
            println!("num {}", i);
            tokio::spawn(async move { 
                loop {
                    let mut sum: i32 = 0;
                    for i in 0..100000000 {
                        sum = sum.overflowing_add(i).0;
                    }
                    println!("sum {}", sum);           
                }
            });
        }
    });
}

在构建多线程runtime时,在on_thread_start 设置cpu亲和。可以看到负载被绑定到了指定的core上。

tokio_cpu_affinity_02

上面的代码只是把负载绑定到了一个core上,那么要绑定多个核怎么办呢?
我们看看下面的代码

pub fn main() {
    let core_ids = core_affinity::get_core_ids().unwrap();
    println!("core num {}", core_ids.len());

    let rt = runtime::Builder::new_multi_thread()
        .enable_all()
        .build()
        .unwrap();

    let mut idx = 2;

    rt.block_on(async {
        for i in 0..8 {
            println!("num {}", i);
            let core_id = core_ids[idx];
            if idx.eq(&(core_ids.len() - 1)) {
                idx = 2;
            } else {
                idx += 1;
            }

            tokio::spawn(async move {
                let res = core_affinity::set_for_current(core_id);
                println!("{}", res);
                loop {
                    let mut sum: i32 = 0;
                    for i in 0..100000000 {
                        sum = sum.overflowing_add(i).0;
                    }
                    println!("sum {}", sum);
                    }
            });
        }
    });
}


代码需要把所有负载绑在 core3和core4上。原理是在派生任务中加入 core_affinity 设置.通过调整idx,将派生并发平均绑定在指定的core上。代码运行的监控如下图。

tokio_cpu_affinity_03

本期关于cpu亲和的话题就聊到这儿,下期见

作者:京东科技 贾世闻

来源:京东云开发者社区

标签:core,--,sum,ids,文盘,let,tokio,println
From: https://www.cnblogs.com/Jcloud/p/17457478.html

相关文章

  • matlab结构化程序设计流程结构
    一、条件转移结构基本形式:f条件表达式语句段end执行流程:若表达式条件成立,执行语句段,否则跳过语句段的执行。若需要多条件转移,一般是三个或以下:if条件表达式1语句段1elseif条件表达式2语句段2else 语句段3end注意事项:if或else中的语句无需{}包围......
  • 《人月神话》 ——七、八、九章
    以下是我读的这本书的第七、八、九章的内容。第七章:"WhyDidtheTowerofBabelFail?"(巴别塔为何失败?)这一章主要探讨了软件开发中的沟通问题。布鲁克斯以巴别塔的故事为比喻,讲述了不同团队成员之间语言、文化和沟通障碍的影响。他强调了软件开发中沟通的重要性,并讨论了如何解......
  • .NET使用System.Speech轻松读取文本
    System.Speech是.NET框架的一部分,提供了语音识别和语音合成的功能。通过使用System.Speech命名空间中的类,开发人员可以在.NET应用程序中实现语音识别功能。在本文中,我将演示如何使用System.Speech.NET,这是开发语音应用程序比较牛逼的内库。它适用于.NET4.x和.NETCore以上版本......
  • git add 时报错 warning: in the working copy of 'package-lock.json', LF will...
    来源:https://blog.csdn.net/qq_43842093/article/details/128471953问题:执行gitadd.时报错: 原因:换行符的问题, Windows下换行符和Unix下的换行符不一样,git会自动转换。 解决办法: 执行如下命令:gitconfig--globalcore.autocrlffalse问题解决 ......
  • Grafana 汉化调试(四)
    Grafana汉化调试(四)Grafana最新的9.5.2版本现在已经支持中文了,不用再安装插件去汉化了1、首先进入用户的个人资料2、把语言类型修改成“中文(简体)”3、保存修改4、这是发现界面已经变成中文了......
  • 案例分享-被*队友的mybatis蠢哭的一天
    昨晚加班的时候被队友拉着看一个mybatis的问题,耗费了我一个小时时间,最后差点没被我打死,实在是觉得滑稽,今天回家写下来跟大伙分享一下。问题现象Invalidboundstatement(notfound),看到这个错我当时就没兴趣了,我说你这不就是xml里没写xxxMapper.java方法对应的语句吗,这还有啥犹......
  • Docker运行Django框架
    Django框架创建django-pg项目目录[root@docker~]#mkdirdocker-compose-django[root@docker~]#cddocker-compose-django/[root@dockerdocker-compose-django]#mkdirdjango-pg在项目目录下创建docker-compose.yml文件该文件定义了两个服务,一个是名为db的Postgres数......
  • 矩阵正定和半正定的概念
    正定矩阵:给定一个大小为  的实对称矩阵  ,若对于任意长度为  的非零向量  ,有  恒成立,则矩阵  是一个正定矩阵。单位矩阵 就是一个正定矩阵半正定矩阵:给定一个大小为  的实对称矩阵  ,若对于任意长度为  的向量  ,有  恒成立,则矩阵  是一个半正定矩阵。 ......
  • Qt里怎么恢复一个被最小化的窗口
    这个需求出现在窗口最小化之后又被再次运行的时候。很多用户往往不去注意窗口是否已经存在,而是经常直接再次执行打开窗口操作。为了拦截这种情况,通常我们会去检测到窗口是否已经存在,如果存在则把它恢复正常,而不是再新创建一个。这个操作是通过ShowNormal()实现的,但这个函数在wi......
  • 1500个心理测试大全题库ACCESS数据库
    今天收集到了一个结构很简单的心理测试题库,所谓的结构很简单是区别于《常用心理测试精选题库ACCESS数据库》、《心理测试性格测试大全ACCESS数据库》等数据库一个测试项目需做几道题然后给出解释,表与表需要关联而言的,这个心理测试很简单,给出一个测试题目,你回答ABCD即给出解释。......