最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

龍芯LoongArch指令集計(jì)算CRC32的速度是MIPS的4倍以上

2021-08-29 18:22 作者:gueenet  | 我要投稿

????????相信凡是與編程或通信相關(guān)的技術(shù)人員都知道CRC32,這是一種常用的數(shù)據(jù)校驗(yàn)編碼。因?yàn)镃RC32編碼的算法很簡(jiǎn)單,所以用于計(jì)算CRC32值的C/C++代碼寫(xiě)法基本上固定,很難有優(yōu)化的余地。通常大家都通過(guò)手寫(xiě)匯編,調(diào)用特定指令集用于CRC32計(jì)算的專(zhuān)用指令來(lái)達(dá)到計(jì)算加速的目的。龍芯以前使用的MIPS以及龍芯自己的擴(kuò)展指令中都沒(méi)有CRC32計(jì)算指令,現(xiàn)在全新的LoongArch指令集中提供了計(jì)算CRC32的專(zhuān)用指令,使計(jì)算CRC32的速度達(dá)到原來(lái)的4倍以上。

????????使用專(zhuān)用指令達(dá)到提速的目的其實(shí)沒(méi)什么可說(shuō)的,但如果不使用專(zhuān)用指令,而僅僅是把C/C++代碼編譯為L(zhǎng)oongArch的二進(jìn)制,就能比MIPS快20%以上呢?是不是就比較有意思了!

????????下面是一段計(jì)算CRC32值的C程序,大多數(shù)計(jì)算CRC32的代碼都應(yīng)該和它相似。函數(shù)CrcGenerateTable用于初始化計(jì)算多項(xiàng)式表,只需要調(diào)用一次。函數(shù)CrcUpdate用于計(jì)算數(shù)據(jù)的CRC32值,只有短短的幾行。


????????我們先使用GCC編譯器 -O參數(shù)編譯,看看CrcUpdate這個(gè)函數(shù)分別編譯為L(zhǎng)oongArch和MIPS有什么區(qū)別:

????????第一眼看到的,就是實(shí)現(xiàn)相同功能時(shí),LoongArch二進(jìn)制的指令數(shù)量要比MIPS少很多。然后呢,就是兩者的指令命名規(guī)則和匯編格式有明顯的差異。最重要的就是它們的二進(jìn)制操作碼完全沒(méi)有相似之處,說(shuō)明這是兩種不同的指令集,無(wú)法二進(jìn)制兼容。最近有一些缺乏專(zhuān)業(yè)素養(yǎng)的媒體以及公司說(shuō)LoongArch只是對(duì)MIPS的擴(kuò)展,把“C/C++源代碼兼容”和“指令集二進(jìn)制兼容”混為一談,還弄不清楚“二進(jìn)制兼容”和“二進(jìn)制翻譯方式兼容”的區(qū)別,不知道他們?cè)趺春靡馑甲苑Q(chēng)技術(shù)博主和科技公司?

? ? ? ? 上面的二進(jìn)制程序都是用-O參數(shù)編譯的,是一種編譯器默認(rèn)的編譯優(yōu)化參數(shù)。我在龍芯3A5000和3A4000上分別使用能使它們較好發(fā)揮性能的編譯參數(shù),對(duì)這段計(jì)算CRC32的C語(yǔ)言程序進(jìn)行測(cè)試,發(fā)現(xiàn)性能差距很大。

????????編碼1GB的數(shù)據(jù),使用MIPS指令集的3A4000(1.8GHz)耗時(shí)6.57秒(單線(xiàn)程),平均每秒約156M字節(jié)。使用LoongArch指令集的3A5000(耗時(shí))3.87秒(單線(xiàn)程),平均每秒約264MB字節(jié)。3A4000和3A5000的CPU主頻有差距,但CPU核心基本一樣。如果把這個(gè)數(shù)據(jù)折算到相同的CPU頻率,3A5000仍然比3A4000高出22.2%。按數(shù)據(jù)量和時(shí)間算,內(nèi)存也不可能是瓶頸(實(shí)測(cè)單通道和雙通道沒(méi)有差距),它們最大的區(qū)別就只剩下指令集了。從上面的編譯結(jié)果就能看出來(lái),LoongArch實(shí)現(xiàn)相同功能使用的指令更少,這就是全新LoongArch指令集的優(yōu)勢(shì)之一了。即便使用更優(yōu)化的編譯參數(shù),結(jié)果也一樣,MIPS指令數(shù)量無(wú)法比LoongArch更少。

????????上面提到使用LoongArch中的CRC專(zhuān)用指令可以超過(guò)“4倍性能”,這也需要展示一番,不然本文就是不完整的。我編寫(xiě)了一個(gè)與CrcUpdate這個(gè)函數(shù)功能相同的LoongArch匯編函數(shù),用它來(lái)與C/C++代碼的編譯結(jié)果進(jìn)行對(duì)比。先看測(cè)試結(jié)果,然后我再解析匯編代碼。


????????當(dāng)把實(shí)測(cè)的CRC32編碼速度都折算到1GHz之后,使用LoongArch指令集的3A5000仍有超過(guò)350MB/s的編碼速度(單線(xiàn)程),是使用MIPS指令集的3A4000的CRC32編碼速度的4倍以上。實(shí)際上對(duì)匯編代碼仍然可以繼續(xù)優(yōu)化,在我進(jìn)行了一些優(yōu)化后,3A5000的CRC32編碼速度超過(guò)了1000MB/s。

????????使用LoongArch中的CRC指令就不需要事先計(jì)算多項(xiàng)式表了,CPU中內(nèi)置了IEEE.802.3多項(xiàng)式(多項(xiàng)式值為0xEDB88320),和Castagnoli多項(xiàng)式(多項(xiàng)式值為0x82F63B78)的表。當(dāng)使用“crc”為指令前綴時(shí),使用就的是IEEE.802.3多項(xiàng)式。當(dāng)使用“crcc”為指令前綴時(shí),使用的就是Castagnoli多項(xiàng)式。

  其實(shí)匯編代碼也不復(fù)雜,畢竟只是一個(gè)很小的函數(shù),幾乎每一行我都加了詳細(xì)注釋?zhuān)驗(yàn)檫@也是我自己學(xué)習(xí)的過(guò)程。因?yàn)橘N代碼容易格式錯(cuò)亂,只好貼成圖片。


????????從上面可以看到,L3標(biāo)簽下面只有4條指令,這個(gè)最主要的循環(huán)中有2條指令是用于處理循環(huán)條件的。那么繼續(xù)優(yōu)化的方法就呼之欲出,只要在一次循環(huán)中多計(jì)算幾次,就可以減少循環(huán)次數(shù)?!發(fā)dptr.d $r12,$r5,0”這條載入數(shù)據(jù)的指令中,最后一個(gè)參數(shù)是立即數(shù),作為取數(shù)據(jù)的偏移量,于是如果把循環(huán)代碼改成下面的樣子,每次循環(huán)就可以計(jì)算16個(gè)字節(jié):


????????以此類(lèi)推,也可以計(jì)算24、32、48……個(gè)字節(jié)。這樣修改之后,代碼中還有其它地方也需要做修改,比如函數(shù)入口處的8字節(jié)對(duì)齊計(jì)算就修改成對(duì)應(yīng)的數(shù)。下面的單字節(jié)循環(huán)也需要修改,不過(guò)也有偷懶的方法,比如想每次循環(huán)計(jì)算64字節(jié),就單獨(dú)寫(xiě)一個(gè)只計(jì)算數(shù)據(jù)長(zhǎng)度為64倍數(shù)的函數(shù)。當(dāng)數(shù)據(jù)長(zhǎng)度大于等于64時(shí),就可以先調(diào)用它一次,把剩下的數(shù)據(jù)再調(diào)用之前的函數(shù)來(lái)計(jì)算,就像下面這樣:


????????LoongArch指令集中的CRC指令并不只是可以計(jì)算單字節(jié)和8字節(jié),它其實(shí)有計(jì)算1、2、4、8字節(jié)的4種格式,后綴分別為“w.b.w”、“w.h.w”、“w.w.w”、“w.d.w”。

????????龍芯LoongArch指令集中除了CRC指令之外,還有許多有趣的指令。比如字節(jié)序翻轉(zhuǎn)指令,在處理網(wǎng)絡(luò)通信數(shù)據(jù)、圖像像素格式轉(zhuǎn)換等的時(shí)候就能用得上。比如取得一個(gè)數(shù)中有多少個(gè)bit為1,在處理mask數(shù)據(jù)時(shí)就非常有用。LoongArch中的原子訪(fǎng)存指令特別豐富,在做多線(xiàn)程互斥、數(shù)據(jù)“無(wú)鎖”訪(fǎng)問(wèn)等功能時(shí)就可以比較靈活。

????????龍芯LoongArch指令集中各種有趣的指令和有趣的用法,大家一起去發(fā)掘吧?!洱埿炯軜?gòu)參考手冊(cè)》您值得擁有!


龍芯LoongArch指令集計(jì)算CRC32的速度是MIPS的4倍以上的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
历史| 商河县| 吉林省| 呼和浩特市| 徐闻县| 正阳县| 舒城县| 东光县| 顺平县| 铜川市| 云南省| 万荣县| 全州县| 儋州市| 禄丰县| 高安市| 阿拉尔市| 古浪县| 克山县| 堆龙德庆县| 马鞍山市| 建湖县| 辽宁省| 颍上县| 探索| 常宁市| 修武县| 江都市| 绥化市| 德清县| 巩义市| 隆化县| 甘孜县| 赤峰市| 濮阳市| 揭阳市| 望城县| 横峰县| 安平县| 三都| 德江县|