0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

文盤Rust -- tokio綁定cpu實踐

jf_wN0SrCdH ? 來源:Rust語言中文社區(qū) ? 2023-06-11 15:32 ? 次閱讀

tokio 是 rust 生態(tài)中流行的異步運行框架。在實際生產中我們如果希望 tokio 應用程序與特定的 cpu core 綁定該怎么處理呢?這次我們來聊聊這個話題。

首先我們先寫一段簡單的多任務程序。

use tokio::runtime;
pub fn main() {
    let rt = runtime::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 環(huán)境,然后派生多個 tokio 并發(fā),每個并發(fā)執(zhí)行一個無限循環(huán)做overflowing_add。overflowing_add函數(shù)返回一個加法的元組以及一個表示是否會發(fā)生算術溢出的布爾值。如果會發(fā)生溢出,那么將返回包裝好的值。然后取元祖的第一個元素打印。

這個程序運行在 Ubuntu 20 OS,4 core cpu。通過nmon的監(jiān)控如下:

326c77c2-0735-11ee-962d-dac502259ad0.png

可以看到每個 core 都有負載。

要想把負載綁定在某一 core 上,需要使用core_affinity_rs(https://github.com/Elzair/core_affinity_rs)。core_affinity_rs是一個用于管理CPU親和力的Rust crate。目前支持Linux、Mac OSX和Windows。官方宣稱支持多平臺,本人只做了linux 操作系統(tǒng)的測試。

我們把代碼修改一下:

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::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親和??梢钥吹截撦d被綁定到了指定的core上。

3280fcf6-0735-11ee-962d-dac502259ad0.png

上面的代碼只是把負載綁定到了一個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,將派生并發(fā)平均綁定在指定的core上。代碼運行的監(jiān)控如下圖。

32a29956-0735-11ee-962d-dac502259ad0.png

本期關于cpu親和的話題就聊到這兒,下期見


聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 應用程序
    +關注

    關注

    37

    文章

    3198

    瀏覽量

    57360
  • Rust
    +關注

    關注

    1

    文章

    226

    瀏覽量

    6497
  • Tokio
    +關注

    關注

    0

    文章

    12

    瀏覽量

    49

原文標題:文盤Rust -- tokio綁定cpu實踐

文章出處:【微信號:Rust語言中文社區(qū),微信公眾號:Rust語言中文社區(qū)】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    Linux進程怎么綁定CPU

    昨天在群里有朋友問:把進程綁定到某個 CPU 上運行是怎么實現(xiàn)的。
    發(fā)表于 10-26 10:26 ?1789次閱讀

    SQLx在Rust語言中的基礎用法和進階用法

    SQLx是一個Rust語言的異步SQL執(zhí)行庫,它支持多種數(shù)據(jù)庫,包括MySQL、PostgreSQL、SQLite等。本教程將以MySQL數(shù)據(jù)庫為例,介紹SQLx在Rust語言中的基礎用法和進階用法
    的頭像 發(fā)表于 09-19 14:32 ?4584次閱讀

    什么是Tokio模塊 Channel?

    Rust 語言是一種系統(tǒng)級編程語言,它具有強類型和內存安全性。Rust 語言中的 Tokio 模塊是一個異步編程庫,它提供了一種高效的方式來處理異步任務。其中,channel 是 Tokio
    的頭像 發(fā)表于 09-19 15:57 ?838次閱讀

    Rust GUI實踐Rust-Qt模塊

    Rust-Qt 是 Rust 語言的一個 Qt 綁定庫,它允許 Rust 開發(fā)者使用 Qt 框架來創(chuàng)建跨平臺的圖形界面應用程序。Qt 是一個跨平臺的應用程序框架,它提供了一系列的工具和
    的頭像 發(fā)表于 09-30 16:43 ?1376次閱讀

    把進程綁定到某個 CPU 上運行是怎么實現(xiàn)?

    昨天在群里有朋友問:把進程綁定到某個 CPU 上運行是怎么實現(xiàn)的。 首先,我們先來了解下將進程與 CPU 進行綁定的好處。 進程綁定
    的頭像 發(fā)表于 07-02 09:55 ?2315次閱讀

    移動端arm cpu優(yōu)化學習筆記第3彈--綁定cpu(cpu affinity)

    本文主要內容是介紹移動端優(yōu)化會涉及到的綁定cpucpu affinity)[2,3]的概念和相關驗證實驗。 作者:梁德澎首發(fā)知乎:[鏈接]
    發(fā)表于 02-07 11:19 ?0次下載
    移動端arm <b class='flag-5'>cpu</b>優(yōu)化學習筆記第3彈--<b class='flag-5'>綁定</b><b class='flag-5'>cpu</b>(<b class='flag-5'>cpu</b> affinity)

    WasmEdge增加了Tokio支持

    WasmEdge 成功地移植了 tokio(一個 Rust 異步運行時)到 Wasm:https://github.com/WasmEdge/tokio。其秘
    的頭像 發(fā)表于 12-05 11:55 ?730次閱讀

    Rust -- 用Tokio實現(xiàn)簡易任務池

    59執(zhí)行完后面就沒有輸出了,如果把max_task設置為2,情況會好一點,但是也沒有執(zhí)行完所有的異步操作,也就是說在資源不足的情況下,Tokio會拋棄某些任務,這不符合我們的預期。
    的頭像 發(fā)表于 04-09 10:24 ?1198次閱讀

    Rust -- rust連接oss

    我們以 [S3 sdk](https://github.com/awslabs/aws-sdk-rust)為例來說說基本的連接與操作,作者驗證過aws、京東云、阿里云。主要的增刪改查功能沒有什么差別。
    的頭像 發(fā)表于 05-12 16:18 ?494次閱讀

    Tokio 模塊的優(yōu)雅停機機制

    在進行高并發(fā)、網(wǎng)絡編程時,優(yōu)雅停機是一個非常重要的問題。在 Rust 語言中,Tokio 是一個非常流行的異步編程框架,它提供了一些優(yōu)雅停機的機制,本文將圍繞 Tokio 模塊的優(yōu)雅停機進行詳細
    的頭像 發(fā)表于 09-19 15:26 ?507次閱讀

    如何使用Tokio 和 Tracing模塊構建異步的網(wǎng)絡應用程序

    Rust 語言中,Tokio 是一個非常流行的異步運行時,它提供了高效的異步 I/O 操作和任務調度。而 Tracing 則是一個用于應用程序跟蹤的框架,它可以幫助我們理解應用程序的行為和性能
    的頭像 發(fā)表于 09-19 15:29 ?549次閱讀

    如何使用 Tokio 模塊的Channel

    Channel 是一種在多線程環(huán)境下進行通信的機制,可以讓線程之間互相發(fā)送消息和共享數(shù)據(jù)。Rust 語言中的 Tokio 模塊提供了一種異步的 Channel 實現(xiàn),使得我們可以在異步程序中方
    的頭像 發(fā)表于 09-19 15:38 ?550次閱讀

    tokio模塊channel中的使用場景和優(yōu)缺點

    Rust 語言的 tokio 模塊提供了一種高效的異步編程方式,其中的 channel 模塊是其核心組件之一。本教程將介紹 tokio 模塊 channel 的除了上文提到的 mspc
    的頭像 發(fā)表于 09-19 15:54 ?635次閱讀

    Tokio 的基本用法

    Tokio 是一個異步 I/O 框架,它提供了一種高效的方式來編寫異步代碼。它使用 Rust 語言的 Futures 庫來管理異步任務,并使用 Reactor 模式來處理 I/O 事件。 本系
    的頭像 發(fā)表于 09-19 16:05 ?679次閱讀

    一次Rust重寫基礎軟件的實踐

    受到2022年“谷歌使用Rust重寫Android系統(tǒng)且所有Rust代碼的內存安全漏洞為零” [1] 的啟發(fā),最近筆者懷著濃厚的興趣也順應Rust 的潮流,嘗試著將一款C語言開發(fā)的基礎軟件轉化
    的頭像 發(fā)表于 01-25 11:21 ?482次閱讀