C++ Low level performance optimize 2 php
上一篇 文章討論了一些底層代碼的優化技巧,本文繼續討論一些相關的內容。html
首先,上一篇文章討論cache missing的重要性時,用了list作比較,目的並非說list沒有用,而是說明cache missing會對性能有重要影響。若是元素很少,而且對象複製的代價很大,那麼list可能就是更好的選擇。其次,這裏討論的大部分是編碼時一些比較底層的技巧,當遇到性能問題時,應該先考慮是否能在高層改進算法,減小運算,實在不行,在考慮這類優化技巧。性能優化的挑戰就在於沒有完美的永遠適用的方案,瞭解這些技巧讓咱們在優化代碼時有更多武器,但最終選擇哪一個方案還須要更加實際狀況,而且以profile的實際數據爲依據來作。c++
1. Data Layout算法
調整數據佈局是常見的優化手段,作此類優化時有幾點須要注意:首先是內存佔用,現代編譯器默認大多以16或32位對齊,所以安全
struct BadLayout { int8_t i0; int32_t i1; int8_t i2; }; struct GoodLayout { int8_t i0; int8_t i2; int32_t i1; };
sizeof(Goodlayout) >= sizeof(BadLayout) 在vs2013默認對齊設置下,BadLayout==12 byte,GoodLayout==8byte。性能優化
其次,常常訪問或者相關的數據應該放到一塊兒,減小cache missing。Going native2013 Andrei Alexandrescu介紹了facebook作的重要性能優化就是把php代碼編譯爲c++代碼,而在代碼轉換中重要的一步就是根據數據的」hotness」從新佈局。佈局
struct BadLayout { auto user0_data0; auto user1_data1; auto user0_data1; auto user1_data0; }; struct GoodLayout { auto user0_data0; auto user0_data1; auto user1_data0; auto user1_data1; };
最後,可維護性!這一點很是重要,對於一些生命週期較長的項目來講,把數據按邏輯組織更易於維護,減小潛在bug的重要性,若是性能差異不大,我一般更願意讓代碼看起來好讀J性能
2. Code cache優化
struct BitBool { bool b0 :1; bool b1 :1; bool b2 :1; } struct NormalBool { bool b0; bool b1; bool b2; }
上次的例子中,這段代碼比較有爭議,讓咱們從時間和空間方面來分析。時間上,由於BitBool須要額外指令來訪問元素,所以效率必定比NormalBool低,但差異很是小,幾乎能夠忽略。再看空間上,但從結構自己看,顯然BitBool更小,可是因爲訪問元素須要額外指令,實際應用中,生成的代碼必定比NormalBool多,讀取訪問的次數越多,生成的代碼也越多(內聯的結果),而代碼也須要佔用內存空間!!cache line中一般一半是代碼,一半是數據。所以,不必定由於BitBool自己小就獲得更好的cache。大部分文章在討論cache missing時都只介紹了數據,而忽略了代碼也須要佔用內存,也會有cache missing。某些遊戲引擎會在update entity時先把對象按照類型排序,就是爲了減小代碼的cache missing。ui
最後,這個例子的目的是讓你們瞭解過分優化可能並不會帶來性能提高,實際應用中兩種寫法的雖然有性能差距,但基本能夠忽略。
3. more about bit field
上一個例子讓我想起了bitfield另外一個微妙的地方,假設f1和f2在兩個不一樣線程中,考慮下面代碼是安全的嗎?
struct BitField { bool b0 : 1; bool b1 : 1; bool b2 : 1; uint8_t i0 :3; } BitField bf; std::mutex mtx1;
std::mutex mtx2; //thread 1 void f1() { mtx1.lock(); bf.b1 = somevalue; mtx1.unlock(); } //thread 2 void f2() { mtx2.lock(); bf.i0 = somevalue; mtx2.unlock(); }
No!!!雖然代碼能夠經過編譯運行,但卻並非線程安全的,由於b1,i0都屬於同一快內存」單元」,所以根本沒法生成只更新b1,可是不寫入i0的代碼!!實際上c++11明確指出了這種狀況會致使race,臨近的bit老是被當作一個」對象」 :)