簡體   English   中英

C / C ++位域與按位運算符相比,可以更快,更好,更便攜地選擇位?

[英]C/C++ bitfields versus bitwise operators to single out bits, which is faster, better, more portable?

我需要以這種方式在字節中打包一些位:

struct  
{  
  char bit0: 1;  
  char bit1: 1;  
} a;  

if( a.bit1 ) /* etc */

要么:

if( a & 0x2 ) /* etc */

從源代碼的清晰性來看,對我來說很明顯位域更整潔。 但是哪個選擇更快? 我知道速度差異不會太大,但是我可以使用其中的任何一個,如果速度更快,更好。
另一方面,我讀到不能保證位域在平台之間以相同順序排列位,並且我希望代碼具有可移植性。

注意:如果您打算回答“個人資料”,可以,我會的,但是由於我很懶,如果有人已經有了答案,那就更好了。
代碼可能是錯誤的,如果需要,您可以糾正我,但請記住此問題的重點,也請嘗試回答。

如果位域使用得當,它們會使代碼更清晰。 我只會將位域用作節省空間的設備。 我見過它們使用的一個常見地方是在編譯器中:類型或符號信息通常由一堆true / false標志組成。 位域在這里是理想的,因為典型程序在編譯時會創建成千上萬個這樣的節點。

我不會使用位域來完成常見的嵌入式編程工作:讀取和寫入設備寄存器。 我更喜歡在這里使用shift和mask,因為您可以准確地得到文檔告訴您的所需位,而不必擔心各種編譯器在實現位域方面的差異。

至於速度,一個好的編譯器將為位域提供與屏蔽相同的代碼。

為了獲得最大的可移植性,我寧願使用第二個示例。 正如尼爾·巴特沃思(Neil Butterworth)所指出的那樣,僅對本機處理器使用位域。 好了,想想看,如果英特爾的x86明天停產,代碼將被卡住,這意味着必須重新實現另一個處理器的位域,如RISC芯片。

您必須從更大的角度看,並問OpenBSD如何使用一個代碼庫將其BSD系統移植到許多平台上? 好的,我承認這有點過頭了,值得商and和主觀,但實際上,如果您要將代碼移植到另一個平台,則可以使用問題中使用的第二個示例來實現。 。

不僅如此,針對不同平台的編譯器將具有自己的填充方式,將編譯器所在的處理器的位字段對齊。 而且,處理器的耐久性如何?

永遠不要把位域當作魔術子彈。 如果您想要處理器的速度並將其固定在其上,即無意移植,則可以隨意使用位域。 不能同時擁有!

由於未知的原因,C位字段從被發明的那一刻就誕生了。 人們不喜歡它們,而是使用按位運算符。 您必須期望其他開發人員不了解C位域代碼。

關於哪個更快:不相關。 任何優化的編譯器(實際上是所有編譯器)都會使代碼以任何表示方式執行相同的操作。 對於C程序員來說,一個普遍的誤解是編譯器只是將關鍵字搜索並替換為匯編語言。 現代編譯器將源代碼用作要實現的目標的藍圖,然后發出通常看起來非常不同但可以達到預期結果的代碼。

第一個是顯式的,無論第二個表達式的速度如何,都容易出錯,因為對結構的任何更改都可能使第二個表達式錯誤。

因此,請使用第一個。

如果要攜帶,請避免使用位域。 而且,如果您對特定代碼的性能感興趣,那么除了編寫自己的測試之外別無選擇。 記住,位域將在后台使用處理器的按位指令。

我認為C程序員傾向於使用位掩碼和邏輯運算來推斷每個位的值的第二種選擇。 可以使用枚舉來設置枚舉,或者通常在涉及更復雜的操作時使用宏來獲取/設置特定位,而不是用十六進制值來填充代碼。 我聽說過,實現結構的位域速度較慢。

在“非便攜式位域”中不要讀太多。 位域有兩個方面,它們是實現定義的:有符號性和布局,一個未指定的域:打包它們的分配單元的對齊方式。 如果您不需要打包效果,使用它們就像函數調用一樣具有可移植性(只要您在需要的地方明確指定一個帶signed關鍵字),這些函數也具有未指定的屬性。

關於性能,配置文件是您可以獲得的最佳答案。 在一個完美的世界中,這兩種著作之間沒有區別。 實際上,可以有一些原因,但是我可以想到一個方向上與另一個方向上一樣多的原因。 而且它可能對上下文非常敏感(例如,無符號和有符號之間在邏輯上無意義的差異),因此請在上下文中進行測量...

綜上所述,因此,在您真正有選擇權的情況下,差異主要是樣式差異(即,如果精確的布局很重要則不是)。 在那種情況下,這是一種優化(大小,而不是速度),因此我傾向於先編寫沒有代碼的代碼,然后在需要時添加它。 因此,位字段是顯而易見的選擇(要做的修改是獲得結果的最小修改,並且包含在定義的唯一位置,而不是擴展到所有使用位置)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM