性无码一区二区三区在线观看,少妇被爽到高潮在线观看,午夜精品一区二区三区,无码中文字幕人妻在线一区二区三区,无码精品国产一区二区三区免费

徐土豆
認(rèn)證:優(yōu)質(zhì)創(chuàng)作者
所在專題目錄 查看專題
C語(yǔ)言中去除不必要的內(nèi)存引用可以有效地提高性能
C語(yǔ)言中內(nèi)循環(huán)和外循環(huán)的位置可能產(chǎn)生性能上的區(qū)別
[C語(yǔ)言朝花夕拾] C語(yǔ)言中的命令行輸入?yún)?shù)判斷
用“位操作”取代“取模操作”判斷奇數(shù)偶數(shù)
c語(yǔ)言運(yùn)行時(shí)出現(xiàn)segment fault的原因
一文理解C語(yǔ)言中的volatile修飾符
作者動(dòng)態(tài) 更多
給定計(jì)算預(yù)算下的最佳LLM模型尺寸與預(yù)訓(xùn)練數(shù)據(jù)量分配
14小時(shí)前
大模型推理時(shí)的尺度擴(kuò)展定律
2天前
世界多胞體與世界模型
1星期前
獎(jiǎng)勵(lì)模型中的尺度擴(kuò)展定律和獎(jiǎng)勵(lì)劫持
1星期前
MeCo——給預(yù)訓(xùn)練數(shù)據(jù)增加源信息,就能減少33%的訓(xùn)練量并且提升效果
2星期前

用“位操作”取代“取模操作”判斷奇數(shù)偶數(shù)

本文轉(zhuǎn)自徐飛翔的“用“位操作”取代“取模操作”判斷奇數(shù)偶數(shù)

版權(quán)聲明:本文為博主原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接和本聲明。

在刷題過(guò)程中,我們經(jīng)常會(huì)遇到需要判斷某個(gè)整數(shù)是奇數(shù)還是偶數(shù)的情況,這個(gè)時(shí)候,我們可能會(huì)采取取模的操作,直接判斷,如:

num % 2 == 0;
num % 2 == 1;

然而,取模操作是非常慢的(按照速度來(lái)說(shuō),位移操作>=加減法>>乘除法,取模,具體見(jiàn)文末的備注),因此我們應(yīng)該盡量避免使用取模操作,在判斷奇數(shù)偶數(shù)時(shí),我們可以用位操作替代取模操作,因?yàn)槲覀冎?,偶?shù)可以被2整除,那么其最低有效位必然是0,而奇數(shù)的相反,則是1,因此可以簡(jiǎn)單用以下語(yǔ)句取代:

num & 0x01 == 0; 
num & 0x01 == 1;

實(shí)際上,在GCC中,其對(duì)“模2”操作的優(yōu)化中,就是用“位與”進(jìn)行取代的[1],如:

cpp_code            uint ix = 3;
0000003c  mov         dword ptr [ebp-40h],3 
cpp_code            bool even = ix % 2 == 0;
00000043  mov         eax,dword ptr [ebp-40h] 
00000046  and         eax,1 
00000049  test        eax,eax 
0000004b  sete        al   
0000004e  movzx       eax,al 
00000051  mov         dword ptr [ebp-44h],eax 

有些平臺(tái),比如LeetCode中,并沒(méi)有這種優(yōu)化,因此需要自己進(jìn)行顯式地優(yōu)化。

然而,我們還需要注意到,通常我們的位操作都是對(duì)無(wú)符號(hào)數(shù)進(jìn)行的,如果對(duì)有符號(hào)數(shù)進(jìn)行操作,可能會(huì)出現(xiàn)0表示的不一致問(wèn)題,例如:

int num = 4;
cout << (num & 0x01) << endl;

這個(gè)應(yīng)該輸出0,實(shí)際上其輸出也是0,那么我們看下一句:

cout << (num & 0x01 == 0) << endl;

這個(gè)我們期望它輸出的是1,表示的確是偶數(shù),但是其實(shí)實(shí)際上運(yùn)行是輸出的0,因?yàn)檫@兩個(gè)0的表示不統(tǒng)一,我們需要顯式將前者轉(zhuǎn)成無(wú)符號(hào)數(shù),如:

cout << ((unsigned int)(num & 0x01) == 0) << endl;

這樣就是輸出期望中的1了,這點(diǎn)需要特別注意下,容易坑到人。

備注: 以AMD k7處理器為例子,常見(jiàn)的算術(shù),邏輯指令的延遲(latency)表[2],這里的延遲指的是輸入數(shù)據(jù)到輸出數(shù)據(jù)之間的時(shí)間,注意到這里提到的延遲是最小值,沒(méi)有考慮到實(shí)際中的內(nèi)存取值,高速緩存missing之類的情況的。

取模操作通常是結(jié)合除法指令DIV實(shí)現(xiàn)的,因此延遲通常可以參考除法的,我們發(fā)現(xiàn),除法的延遲特別的大,而乘法其次,加減法,邏輯運(yùn)算通常只需要一個(gè)機(jī)器周期即可。

Reference

[1]. https://stackoverflow.com/questions/3909648/identify-odd-even-numbers-binary-vs-mod

[2]. https://www.agner.org/optimize/instruction_tables.pdf

[3]. https://bbs.csdn.net/topics/340234342

聲明:本內(nèi)容為作者獨(dú)立觀點(diǎn),不代表電子星球立場(chǎng)。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請(qǐng)聯(lián)系:editor@netbroad.com
覺(jué)得內(nèi)容不錯(cuò)的朋友,別忘了一鍵三連哦!
贊 2
收藏 3
關(guān)注 52
成為作者 賺取收益
全部留言
0/200
成為第一個(gè)和作者交流的人吧