簡體   English   中英

使用uint8,uint16等

[英]Usage of uint8, uint16 etc

目前我正在使用針對32位MIPS平台的代碼庫(C,C ++混合)。 處理器是一個相當現代的處理器[只是提到我們有很好的處理能力和內存]。

代碼庫使用數據類型,如uint8 [1字節寬無符號整數],uint16 [2字節寬無符號整數],uint32 [4字節寬無符號整數]等。

我知道在將代碼移植到不同平台時這些構造的用法是如何有用的。

我的問題是:

  1. 使用uint16有什么用/有用uint32也足夠了(如果有的話)?

  2. 在使用較短的數據類型(考慮數據對齊)時,是否可以節省內存使用量?

  3. 如果要節省幾個字節的內存,在現代硬件中做些什么是明智的嗎?

使用uint16有什么用/有用uint32也足夠了(如果有的話)?

如果這些uint16s是數組或結構的一部分,則可以節省內存,並且可能能夠處理比在相同數組或結構中使用uint32s更大的數據集。 這真的取決於你的代碼。

數據協議和文件格式可以使用uint16s ,它可能不正確使用uint32s代替。 這取決於格式和語義(例如,如果您需要將值從65535回繞到0,則uint16將自動執行此操作,而uint32將不會這樣做)。

OTOH,如果那些uint16s只是單個局部或全局變量,用32位替換它們可能沒有顯着差異,因為它們可能由於對齊而占用相同的空間並且它們作為32位參數傳遞(在堆棧上)或者在MIPS中或者在寄存器中)。

在使用較短的數據類型(考慮數據對齊)時,是否可以節省內存使用量?

可能會有節省,特別是當uint16s是許多結構的一部分或大數組的元素時。

如果要節省幾個字節的內存,在現代硬件中做些什么是明智的嗎?

是的,你降低了內存帶寬(這總是一件好事),並且當你操作較少的數據時,你經常會降低各種緩存未命中(數據緩存和TLB)。

首先,如果您定義了uint16等類型,它們在哪里定義? 它們不是標准類型,因此將在某些專有標題中定義 - 可能是您的或可能由某些第三方庫提供; 在這種情況下,您必須問自己該代碼的可移植性,以及您是否正在創建在某些其他應用程序中可能沒有意義的依賴項。

另一個問題是許多庫(不明智的IMO)使用各種名稱定義這樣的類型,例如UINT16,uint16,U16 UI16等,它變得有點像確保類型協議和避免名稱沖突的噩夢。 如果這樣的名稱定義 ,他們應該理想地被放置在一個命名空間或給定庫特定的前綴以表示它們與使用被定義什么庫,例如rtos::uint16rtos_uint16

由於ISO C99標准庫在stdint.h中提供了標准的位長特定類型,因此您應該優先使用它們在專有或第三方標頭中定義的任何類型。 這些類型具有_t后綴,例如uint16_t 在C ++中,它們可以放在std:: namespace中(盡管這不是給定的,因為在C99中引入了頭文件)。

1]使用uint16有什么用/有益,uint32也足夠了(如果有的話)?

除了我之前的建議,更喜歡stdint.huint16_t ,至少有兩個合理的理由使用長度特定的類型:

  1. 匹配特定的硬件寄存器寬度。
  2. 在不同體系結構中實施通用且兼容的API。

2]在使用較短的數據類型(考慮數據對齊)時,是否可以節省內存使用量?

可能,但如果記憶不是你的問題,那就不是使用它們的好理由。 值得考慮的可能是大型數據對象或數組,但全球應用很少值得努力。

3]如果要節省幾個字節的內存,在現代硬件中做些什么是明智的嗎?

見[2]。 然而,“ 現代硬件 ”並不一定意味着大量資源; 例如,有大量的32位ARM Cortex-M器件,只有幾Kb的RAM。 這更多是關於模具空間,成本和功耗,而不是設計或建築時代。

cstdint有不同用途的typedef加載。

  • intN_t表示特定寬度
  • int_fastN_t表示最快的整數,至少有N位
  • int_leastN_t表示最小整數,至少有N位
  • 他們unsigned等價物

您應該根據自己的情況選擇。 std::vector存儲數千個而不進行大量計算? intN_t可能是你的男人。 需要快速計算少量整數? int_fastN_t可能是你的家伙。

答。 1.軟件具有一定的要求和規范,嚴格說明在編碼/解碼或其他某些使用時僅占用參數的8/16位。 因此,即使你將一個大於127的值分配到u8中,它也會自動為你修剪數據。

答。 2.我們不應該忘記我們的編譯器超越智能來進行優化,無論是內存還是復雜性。 因此,建議盡可能使用較小的內存。

答。 3.當然,在現代h / w中節省記憶是有意義的。

必須檢查生成的機器代碼/匯編器以驗證是否有任何代碼保存。 在RISC類型架構中,典型的立即數是16位,但是使用uint16_t無論如何都會消耗一個完整的32位寄存器 - 因此,如果使用int類型,但是提交使用接近零的值將產生相同的結果並且更加可移植。

在現代平台中,IMO節省內存也是值得的。 更嚴格的代碼可以帶來更好的電池續航時間和更流暢的用戶體驗。 但是,我建議只在使用(大型)數組時,或者當變量映射到某個真實的HW資源時,才能對大小進行微管理。

PS。 編譯器很聰明,但編寫它們的人現在可以使它們變得更好。

使用uint16_t而不是uint32_t可以節省內存。 它也可能是硬件約束(例如,某些外設控制器實際上發送了16位!)但是,它可能不值得使用它,因為緩存和對齊考慮(你真的必須進行基准測試)。

使用uint16有什么用/有用uint32也足夠了(如果有的話)?

有些CPU中unsigned char是16位值。 如果不使用typedef,單元測試這樣的代碼會很困難(uint16只是適當類型的typedef)。

此外,通過使用這些typedef,在不存在許多問題的情況下在不同平台上構建更容易。

在使用較短的數據類型(考慮數據對齊)時,是否可以節省內存使用量?

不,這不是重點。 如果uint16unsigned short的typedef,那么你可以在任何地方使用unsigned short ,但是你可能在不同的平台上獲得不同的類型。

當然,使用較小的類型將減少內存消耗。 例如,使用uint16而不是uint32,但僅限於使用數組。

如果要節省幾個字節的內存,在現代硬件中做些什么是明智的嗎?

這取決於平台:

  • 內存使用量減少意味着緩存丟失率降低
  • 如果支持,則有SIMD功能處理16位數據

您的問題的答案歸結為一個關鍵概念:數據有多大? 如果你正在處理很多,那么使用較小數據類型的好處是顯而易見的。 可以這樣想:只需計算新發現的最大已知質數,就可以在典型的工作站上耗盡內存。 這個數字本身需要超過一千兆字節才能存儲。 這不包括計算實際數量。 如果您使用的是厚數據類型而不是瘦數據類型,則可能需要使用兩千兆字節。 一個簡單的例子,但仍然是一個好的例子。

使用精確的寬度整數類型(如int32_t和friends)可以避免在intlong具有不同大小的平台之間的符號擴展錯誤。 例如,當應用位掩碼或位移時,這些可能發生。 如果你對這些操作long ,例如,你的代碼適用於32位long ,它可能會打破一個64位long 另一方面,如果你使用uint32_t ,你就會知道無論平台如何,你會得到什么結果。

它們對於在平台之間交換二進制數據也很有用,您只需要擔心存儲數據的字節順序而不是位寬; 如果你把一個int64_t寫入一個文件,你知道在另一個平台上你可以讀取它並將其存儲到int64_t 如果你正在寫了一個long ,而不是這是在一個平台上為64位,你可能最終需要一個long long的另一個平台,因為long只有32位。

保存內存通常不是原因,除非您談論的是非常有限的環境(嵌入式內容)或大型數據集(如具有5000萬個元素的數組等)。

暫無
暫無

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

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