RM新时代网站-首页

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

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

最大化Rust性能:編譯器優(yōu)化的比較分析

jf_wN0SrCdH ? 來(lái)源:coding到燈火闌珊 ? 2023-05-29 15:31 ? 次閱讀

Rust以其獨(dú)特的安全性、速度和并發(fā)性組合而迅速流行。但是與其它任何語(yǔ)言一樣,要充分利用Rust需要的不僅僅是理解它的語(yǔ)法和習(xí)慣用法——還需要深入了解如何有效地利用和優(yōu)化它的編譯器。

為了說(shuō)明這一點(diǎn),我們?cè)O(shè)計(jì)了一個(gè)實(shí)際用例——一個(gè)Actix Web應(yīng)用程序中的矩陣乘法任務(wù)。這種cpu密集型操作為分析各種編譯器優(yōu)化提供了一個(gè)完美的場(chǎng)景。

隨著實(shí)驗(yàn)的深入,我們將調(diào)整Cargo.toml文件的設(shè)置。利用特定的構(gòu)建標(biāo)志,甚至交換內(nèi)存分配器。通過(guò)測(cè)量每次更改對(duì)性能的影響,我們將對(duì)Rust的編譯器優(yōu)化有一個(gè)全面的了解。

實(shí)際用例

我們使用Actix Web開(kāi)發(fā)了一個(gè)緊湊的應(yīng)用程序,具有唯一的路由/matrix-multiplication。這個(gè)接口接收一個(gè)JSON數(shù)據(jù),帶有一個(gè)屬性:n。

在接收到請(qǐng)求后,應(yīng)用程序立即開(kāi)始行動(dòng),動(dòng)態(tài)地生成兩個(gè)大小為n x n的矩陣,在矩陣中隨機(jī)填充一些數(shù)據(jù)。然后將這些矩陣相乘在一起,將計(jì)算的結(jié)果返回給用戶。

新建一個(gè)Rust項(xiàng)目:

cargonewcompiler-optimizations
然后在Cargo.toml文件中寫入如下內(nèi)容:
[dependencies]
anyhow="1.0.71"
actix-web="4.3.1"
dotenv="0.15.0"
serde={version="1.0",features=["derive"]}
serde_json="1.0.96"
log="0.4.17"
env_logger="0.10.0"
serde_derive="1.0.163"
rand="0.8.5"
mimalloc={version="0.1.37",default-features=false}

[profile.release]
lto=true
codegen-units=1
panic="abort"
strip=true
在src/main.rs中寫入如下代碼:
usestd::env;
userand::Rng;

useactix_web::{App,get,post,HttpResponse,HttpServer,middleware,web};
useanyhow::Result;
useserde::{Deserialize,Serialize};

#[global_allocator]
staticGLOBAL:mimalloc::MiMalloc=mimalloc::MiMalloc;

#[derive(Debug,Clone,Serialize,Deserialize)]
structMessage{
pubmessage:String,
}

#[derive(Debug,Clone,Serialize,Deserialize)]
structMatrixSize{
pubn:usize,
}

#[derive(Debug,Clone,Serialize,Deserialize)]
structMatrixResult{
pubmatrix:Vec>,
}

#[get("/healthz")]
asyncfnhealth()->HttpResponse{
HttpResponse::Ok().json(Message{
message:"healthy".to_string(),
})
}

asyncfnnot_found()->HttpResponse{
HttpResponse::NotFound().json(Message{
message:"notfound".to_string(),
})
}

#[post("/matrix-multiplication")]
asyncfnmatrix_multiplication(size:web::Json)->HttpResponse{
letn=size.n;
letmatrix_a=generate_random_matrix(n);
letmatrix_b=generate_random_matrix(n);
letresult=multiply_matrices(&matrix_a,&matrix_b);

HttpResponse::Ok().json(MatrixResult{matrix:result})
}

fngenerate_random_matrix(n:usize)->Vec>{
letmutrng=rand::thread_rng();
(0..n).map(|_|(0..n).map(|_|rng.gen_range(0..nasi32)).collect()).collect()
}

fnmultiply_matrices(matrix_a:&Vec>,matrix_b:&Vec>)->Vec>{
leta_rows=matrix_a.len();
leta_cols=matrix_a[0].len();
letb_cols=matrix_b[0].len();

letmutresult=vec![vec![0;b_cols];a_rows];

foriin0..a_rows{
forjin0..b_cols{
forkin0..a_cols{
result[i][j]+=matrix_a[i][k]*matrix_b[k][j];
}
}
}

result
}

#[actix_web::main]
asyncfnmain()->Result<()>{
env_logger::new().default_filter_or("info"));
letport=env::var("PORT").unwrap_or_else(|_|"8080".to_string());

HttpServer::new(move||{
App::new()
.wrap(middleware::default())
.service(health)
.service(matrix_multiplication)
.default_service(web::route().to(not_found))
})
.bind(format!("0.0.0.0:{}",port))?
.run()
.await.expect("failedtorunserver");

Ok(())
}

優(yōu)化設(shè)置

1,Cargo.toml配置文件配置了-[profile.release]部分,用于調(diào)整優(yōu)化性能。我們使用了以下優(yōu)化設(shè)置:

lto = true:用于啟用鏈路時(shí)間優(yōu)化;

codegen-units = 1:即在整個(gè)crate中使用最高級(jí)別優(yōu)化;

panic = "abort":發(fā)生panic時(shí)調(diào)用abort而不是unwind;

strip = true:通過(guò)移除debug符號(hào)來(lái)減小二進(jìn)制大小。

2,構(gòu)建標(biāo)識(shí)——通過(guò)設(shè)置RUSTFLAGS= " -c target-cpu=native ",我們可以確保編譯器根據(jù)機(jī)器的特定架構(gòu)來(lái)優(yōu)化構(gòu)建。

3,備用內(nèi)存分配器——我們還嘗試了mimalloc內(nèi)存分配器,對(duì)于某些工作負(fù)載,它可以提供比默認(rèn)分配器更好的性能特征。

測(cè)試

為了對(duì)Actix Web API進(jìn)行負(fù)載測(cè)試,我們將使用一個(gè)功能強(qiáng)大但輕量級(jí)的工具——Drill。

為了模擬高負(fù)載,我們的測(cè)試參數(shù)將包括兩個(gè)場(chǎng)景中的500個(gè)并發(fā)請(qǐng)求——一個(gè)有10,000次迭代,另一個(gè)有20,000次迭代。這實(shí)際上分別達(dá)到了50,000和100,000個(gè)請(qǐng)求。

測(cè)試將在各種配置下進(jìn)行,以獲得全面的性能視圖,如下所列:

1,cargo run :構(gòu)建一個(gè)沒(méi)有任何優(yōu)化的開(kāi)發(fā)版本(標(biāo)記為“D”)。

2,cargo run --release:構(gòu)建一個(gè)沒(méi)有任何優(yōu)化的發(fā)布版本(標(biāo)記為“R”)。

3,RUSTFLAGS="-C target-cpu=native" cargo run --release:根據(jù)機(jī)器的特定架構(gòu)來(lái)優(yōu)化構(gòu)建一個(gè)發(fā)布版本,(標(biāo)記為“ROpt”)。

4,與上一個(gè)命令一樣,但是在代碼中采用了MimAlloc的內(nèi)存分配器(表示為'ROptMimAlloc')。

結(jié)果

|BuildType|TotalTime(s)|Requestspersecond|
|---|---|---|
|DevBuildUnoptimized50k|71.3|701.45|
|ReleaseBuildUnoptimized50k|27.0|1849.95|
|ReleaseBuildOptimized(flags)50k|25.8|1937.80|
|ReleaseBuildOptimized(flags+mimalloc)50k|26.7|1873.65|
|ReleaseBuildUnoptimized100k|52.1|1918.27|
|ReleaseBuildOptimized(flags)100k|51.7|1934.59|
|ReleaseBuildOptimized(flags+mimalloc)100k|51.1|1955.07|

94020f4c-fdee-11ed-90ce-dac502259ad0.png

941072c6-fdee-11ed-90ce-dac502259ad0.png

從50k請(qǐng)求測(cè)試開(kāi)始,未優(yōu)化的開(kāi)發(fā)構(gòu)建每秒能夠處理大約701.45個(gè)請(qǐng)求,但是當(dāng)代碼在發(fā)布模式下編譯時(shí),每秒的請(qǐng)求飆升到1849.95個(gè)。這展示了Rust編譯器在從開(kāi)發(fā)模式切換到發(fā)布模式時(shí)所產(chǎn)生的顯著差異。

使用針對(duì)本機(jī)CPU架構(gòu)的構(gòu)建標(biāo)志添加優(yōu)化,進(jìn)一步提高了性能,達(dá)到每秒1937.80個(gè)請(qǐng)求。

當(dāng)我們加入mimalloc(備用內(nèi)存分配器)時(shí),每秒請(qǐng)求數(shù)略微下降到1873.65。這表明,雖然mimalloc可以提高內(nèi)存使用效率,但它不一定能在每個(gè)場(chǎng)景中都能提高請(qǐng)求處理速度。

轉(zhuǎn)到100k個(gè)請(qǐng)求測(cè)試,有趣的是,未優(yōu)化版本和優(yōu)化版本之間的性能差異不那么明顯。未優(yōu)化的版本實(shí)現(xiàn)了每秒1918.27個(gè)請(qǐng)求,而優(yōu)化的版本(帶和不帶mimalloc)分別達(dá)到了每秒1934.59和1955.07個(gè)請(qǐng)求。

這表明,當(dāng)處理大量請(qǐng)求時(shí),我們優(yōu)化的影響變得不那么明顯。盡管如此,即使在更重的負(fù)載下,構(gòu)建優(yōu)化仍然能提供最佳性能。





原作者:劉清

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

    關(guān)注

    0

    文章

    193

    瀏覽量

    25747
  • JSON
    +關(guān)注

    關(guān)注

    0

    文章

    117

    瀏覽量

    6963
  • rust語(yǔ)言
    +關(guān)注

    關(guān)注

    0

    文章

    57

    瀏覽量

    3009
收藏 人收藏

    評(píng)論

    相關(guān)推薦

    使用Rust優(yōu)化Python性能

    在數(shù)據(jù)分析領(lǐng)域Python無(wú)疑是最流行的編程語(yǔ)言,但是Python有一個(gè)硬傷就是作為一個(gè)編譯語(yǔ)言在性能上有些微的欠缺。而同樣最流行的語(yǔ)言Rust則在
    的頭像 發(fā)表于 11-01 15:59 ?897次閱讀
    使用<b class='flag-5'>Rust</b><b class='flag-5'>優(yōu)化</b>Python<b class='flag-5'>性能</b>

    性能最大化Δ-Σ 轉(zhuǎn)換

    時(shí)鐘和PGA 的調(diào)整,相同數(shù)據(jù)速率在性能方面會(huì) 有所不同。在優(yōu)化數(shù)據(jù)轉(zhuǎn)換結(jié)果時(shí),對(duì)于這些方方面面做到完全了解并非易事。另外一些問(wèn)題還包 括輸入阻抗、濾波響應(yīng)、抗混疊,以及長(zhǎng)期漂移。性能
    發(fā)表于 10-21 11:24

    [轉(zhuǎn)]LabVIEW實(shí)現(xiàn)窗口最大化和最小化

    分享VI程序 代碼名稱:LabVIEW實(shí)現(xiàn)窗口最大化和最小化 適用平臺(tái):LabVIEW8.2.x LabVIEW8.5代碼作者:LaRisa_S 版權(quán)所有:LaRisa_S 原創(chuàng)/轉(zhuǎn)載:轉(zhuǎn)載代碼
    發(fā)表于 03-08 14:56

    如何使應(yīng)用程序開(kāi)機(jī)運(yùn)行最大化

    我現(xiàn)在生成一個(gè)應(yīng)用程序并開(kāi)機(jī)啟動(dòng)了,但是如何啊能讓他啟動(dòng)是最大化顯示呢現(xiàn)在一開(kāi)機(jī)啟動(dòng)不是最大化啊。。。。。。很苦惱啊,希望大家指點(diǎn)
    發(fā)表于 05-11 20:57

    如何實(shí)現(xiàn)能源效率最大化?

    如何設(shè)計(jì)智能燃?xì)獗砗退韺?shí)現(xiàn)能源效率最大化
    發(fā)表于 05-13 07:18

    怎樣去實(shí)現(xiàn)OTDR/iOLM長(zhǎng)期性能最大化?

    怎樣去實(shí)現(xiàn)OTDR/iOLM長(zhǎng)期性能最大化?
    發(fā)表于 05-24 07:15

    SIMD計(jì)算機(jī)的優(yōu)化編譯器設(shè)計(jì)

    利用處理的相關(guān)資源,提高編譯器優(yōu)化性能和增強(qiáng)代碼可適應(yīng)性是SIMD處理優(yōu)化編譯的關(guān)鍵。該文基
    發(fā)表于 04-03 08:47 ?30次下載

    最大化自動(dòng)化測(cè)試系統(tǒng)的精度

    最大化自動(dòng)化測(cè)試系統(tǒng)的精度 引言 在設(shè)計(jì)自動(dòng)化測(cè)試系統(tǒng)時(shí),精度的最大化通常是關(guān)鍵的考慮因素。確定如何最大化精度總是很困難
    發(fā)表于 06-13 15:02 ?714次閱讀
    <b class='flag-5'>最大化</b>自動(dòng)化測(cè)試系統(tǒng)的精度

    編譯器_keil的優(yōu)化選項(xiàng)問(wèn)題

    keil編譯器優(yōu)化選項(xiàng)針對(duì)ARM,對(duì)STM32編譯的一些優(yōu)化的問(wèn)題
    發(fā)表于 02-25 14:18 ?3次下載

    編譯器優(yōu)化對(duì)函數(shù)的影響

    編譯器如gcc,可以指定不同的優(yōu)化參數(shù),在某些條件下,有些函數(shù)可能會(huì)被優(yōu)化掉。
    的頭像 發(fā)表于 06-22 14:58 ?2827次閱讀
    <b class='flag-5'>編譯器</b><b class='flag-5'>優(yōu)化</b>對(duì)函數(shù)的影響

    社交網(wǎng)絡(luò)影響力最大化算法及研究綜述

    社交網(wǎng)絡(luò)影響力最大化算法及研究綜述
    發(fā)表于 06-02 14:36 ?6次下載

    基于互信息最大化的Raptor碼優(yōu)化設(shè)計(jì)方法

    基于互信息最大化的Raptor碼優(yōu)化設(shè)計(jì)方法
    發(fā)表于 07-02 11:47 ?8次下載

    最大化Rust性能編譯器優(yōu)化比較分析

    Rust以其獨(dú)特的安全性、速度和并發(fā)性組合而迅速流行。但是與其它任何語(yǔ)言一樣,要充分利用Rust需要的不僅僅是理解它的語(yǔ)法和習(xí)慣用法——還需要深入了解如何有效地利用和優(yōu)化它的編譯器。
    的頭像 發(fā)表于 05-29 16:17 ?1977次閱讀
    <b class='flag-5'>最大化</b><b class='flag-5'>Rust</b><b class='flag-5'>性能</b>:<b class='flag-5'>編譯器</b><b class='flag-5'>優(yōu)化</b>的<b class='flag-5'>比較</b><b class='flag-5'>分析</b>

    編譯器優(yōu)化選項(xiàng)

    一個(gè)程序首先要保證正確性,在保證正確性的基礎(chǔ)上,性能也是一個(gè)重要的考量。要編寫高性能的程序,第一,必須選擇合適的算法和數(shù)據(jù)結(jié)構(gòu);第二,應(yīng)該編寫編譯器能夠有效優(yōu)化以轉(zhuǎn)換成高效可執(zhí)行代碼的
    的頭像 發(fā)表于 11-24 15:37 ?889次閱讀
    <b class='flag-5'>編譯器</b>的<b class='flag-5'>優(yōu)化</b>選項(xiàng)

    TVM編譯器的整體架構(gòu)和基本方法

    。但是這其中也去思考了一下基于FPGA加速編譯器架構(gòu)。在FPGA深度學(xué)習(xí)加速中,編譯器除了需要自動(dòng)化生成指令外,還要優(yōu)化指令的結(jié)構(gòu),來(lái)
    的頭像 發(fā)表于 11-30 09:36 ?2395次閱讀
    TVM<b class='flag-5'>編譯器</b>的整體架構(gòu)和基本方法
    RM新时代网站-首页