2016-07-02 74 views
2

假設一uint16_t我創建了一個模板參數等於多少uint8_t就是我要串起來成一個大INT類。是治療2個uint8_ts爲低效率

這樣我可以創建這樣一個巨大的INT:

SizedInt<1000> unspeakablyLargeNumber; //A 1000 byte number 

現在的問題是:我在使用uint8_t!而非使用內置型較大殺死了我的速度。

例如:

SizedInt<2> num1; 
uint16_t num2; 

num1num2相同的速度,或者是num2快?

+0

我期望'num2'更快,因爲它的操作可以在單個指令中完成,而'num1'將在其uint8_t'成員上至少需要兩次操作。 – Cornstalks

+0

如果你使用至少16位處理器,最有可能'num2'將會更快,因爲對於許多操作,將使用單CPU指令而不是(更復雜的)SizedInt方法。但即使使用8位處理器,我也懷疑這些方法會超越編譯器構建的代碼。 – mvidelgauz

回答

4

這無疑將慢於使用uint8_t[2]而不是uint16_t。例如,除此之外,還可以使用其他方法。爲了獲得uint8_t[2]速度高達uint16_t速度,編譯器必須弄清楚如何翻譯你的插件用攜帶的邏輯和融合的多條指令到一個單一的,更廣泛的加法。我確信某些編譯器有時可以進行這種優化,但是有很多情況可能會使優化變得不可能或不可能。

在某些體系結構上,這甚至適用於加載/存儲,因爲uint8_t[2]通常與uint16_t有不同的對齊要求。

典型BIGNUM的庫,例如GMP,上有方便的架構最大話的工作。在x64上,這意味着使用uint64_t而不是像uint8_t這樣較小的東西的數組。在現代微處理器上添加兩個64位數字是相當快的,實際上,它通常與添加兩個8位數字的速度相同,更不用說通過在小數字陣列中傳播進位位引入的數據依賴性。這些數據依賴性意味着您通常只會在每個時鐘週期添加數組中的一個元素,所以您希望這些元素儘可能大。 (在硬件層面上,有一些特殊的技巧可以讓進位在整個64位操作中快速移動,但這些技巧在軟件中是不可用的。)

如果您願意,您可以隨時使用模板特化來選擇正確尺寸的基元來製作你想要的最節省空間的小塊。否則,使用uint64_t的數組更爲典型。

如果您有選擇,通常通常最好簡單地使用GMP。 GMP的部分是用匯編語言編寫的,以使得bignum操作比其他方式快得多。

2

您可能會由於降低循環開銷得到更大的類型更好的性能。但是,這裏的折衷是更好的速度,而選擇尺寸的靈活性更低。

例如,如果大部分的數字是,比方說,5個字節長,切換到unit_16將需要一個額外的字節的開銷。這意味着20%的內存開銷。另一方面,如果我們談論的是真正的大數字,比如50個字節或更多,內存開銷將會小得多 - 大約2%,所以以更小的成本實現速度的提高。