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老是被当作一个”对象” :)