C 優化和計算速度 碎碎念

2022-04-01 15:42:10 字數 2438 閱讀 6788

實現乙個檔案編碼(冗餘)方式,各種找資料,最後使用伽羅瓦域+線性方程組。

注:**中的類暫時不想公開,以後我覺得拿得出手的時候,會貼出來。

以上是背景。

以下是**思路及其變化:

基礎:乙個使用高斯消元法線性方程組的matrix類。乙個有限域(伽羅瓦域)運算的類galois_field。

最初都是網上找來的**,或存在於開源專案,或是好心人共享的**。

拿來後閹割掉用不到的部分,全部抽象畫為模板類。

最初使用乙個basecomputer類,virtual了add,min,mul,div四個純虛函式。

galois_field繼承自basecomputer,實現了基於有限域的基本運算法則。

然後matrix類建構函式包含乙個basecomputer指標,之後內部所有運算使用basecomputer完成。

最後給出value_t,可以自定義內部運算使用的資料型別。如果你願意的話,使用biginteger,甚至rational(有理數)也是可以的。(請自己負責資料溢位)

1 template

2class base_computer

3 ;

1 templateint bits, int polynomial>

2class galois_field : public base_computer

3 ;

1 template

2class matrix

3 ;

階段性成果:

資料型別使用unsigned short, 運算器使用galois_field(被typedef為galois_field_16)

測試64元方程組,預定解,隨機64組係數,當場構建乙個64x65的矩陣,交給matrix類解出驗證結果是否正確。

重複10000次,耗時42秒。

改進:42秒真心慢,思考應該是純虛函式的vptr跳轉,以及使用方式,使得c++優於c語言的特性完全沒有發揮出來。

繼續改進,basecomputer類不要了。galois_field的所有成員改成靜態,matrix的運算器也由模板管理。所有的模板,可能頻繁呼叫的都標記inline。

最後實現乙個templateclass default_compute,用作matrix類的預設引數。

1 template

2class default_computer

3 8 inline static value_t min(const value_t &left, const value_t &right)

9 inline static value_t mul(const value_t &left, const value_t &right)

10 inline static value_t div(const value_t &left, const value_t &right)

11 };

1 templateint bits, int polynomial>

2class galois_field

3 ;

1 templateclass computer_t = default_computer>

2class matrix

3 ;

階段性成果:

重複上面的測試,時間變成了22秒。

此時手賤,把資料型別改成double,運算器使用default_computer。

重複上面的測試,時間是9秒。

上面的9秒是失誤,不小心引入特殊資料了。

對矩陣內部計算又調整優化了一下。

以下是測試**。

1

int main()

29 }

30 matrix.gasuss();

31 }

32 cout << clock() - begin << endl;

33 system("

pause

");34

return

0;35 }

36

就算排除掉特殊資料,結果依然是令人沮喪的。double作為運算型別,使用原本的加減乘除,要比伽羅瓦域構的計算快一倍以上。

思考:從虛函式表改變為內聯展開的模板,縮短了近一半的時間,可見當呼叫次數累計到可觀的程度也是非常可怕的,當然,這也是c++比c高效的一部分原因。

伽羅瓦域的加減法是一樣的,都是異或。那麼速度一定比double快,但是乘除法就不同了。

伽羅瓦域的乘除需要3次查表,1次布林運算,1或2次加減運算,最少需要訪問5次記憶體。

double的話,就算是乘除法,所有操作也都是在暫存器完成的。

至此,想說的也說完了。

C語言碎碎念

對於if判斷句,一些情況下可以進行如下簡寫 if falg 可簡寫成以下格式 flag printf ok n 結構體的比較與複製 struct node node temp1 4 node temp2 105 15 結構體陣列比較 memcmp temp1,temp2 0 sizeof temp1...

c 碎碎念之一

以前大學的時候用過c,到現在本科畢業3年,一直都是c 和c混合用,其實也就是c加類吧。算得上一種小熟練而已,因為程式畢竟只是工具,以後應該畫很多心思在演算法上,要不然博士怎麼畢業呢?結合最近幾個月來調的這個平台程式,做一點總結,相當於很碎碎念,瑣碎的一些小心得。一 少用全域性變數 為了 的移植性,盡...

碎念 工程和技術

不知道別人會怎麼樣,在下反正經常容易陷入到技術論中,總會有些潔癖地去想問題。明明乙個有可能並不佔主要執行時間的函式,卻總想用乙個更好的方法去優化它,之類的。最近在公司做的乙個系統進行到關鍵階段了,有時候一些一開始不會去考慮的細節才是工程上最重要的。雖然口頭上經常掛著軟工那些東西,但到具體的實踐過程中...