Re: [分享] 面向對象編程從骨子裡就有問題
※ 引述《mahoihei (Alvar)》之銘言:
: 早上看到一篇對個人來說很衝擊性的文章
: http://goo.gl/z4Fa3
: 為什麼說是很衝擊性,因為我自己的編程基礎由oop開始的
: 而在oop design更是我在這個領域最喜愛的地方
: 想問大家對這篇文章有什麼見解??
點進去看這個 URL,幾乎只是引述別人所講的隻字片語
這樣子作文風格,不太對我的胃口,看起來很像是直銷傳單中所慣用的技倆
不過文章末尾有 3 個 link,最後一個是 Sony PS3 RD 所寫的投影片
我覺得這份投影片倒是滿值得參考的
指出在 game design 時某些地方使用純 OOP 實作,會帶來不良後果
(Tony Albrecht,現在是一家公司的 founder)
----------
投影片中的範例,其中之一提到,以目前眾家 compiler 的實作中
會將同一個物件的所有 member variable 所需的記憶體配置在同一塊區域內
(以物件本身作為 memory locality)
但這個模式,在重複性大量資料處理中,卻會發生一個嚴重的副作用:
會使得 CPU 對 memory access 時的 cache miss rate 拉升
以致於效能嚴重低落
以 CPU 與 RAM 於半導體技術進步速度,CPU 的進步比 RAM 的進步快非常多,
以致於現今 CPU 存取 RAM,以 Intel 所提供的資料
http://www.gdcvault.com/play/1014645/-SPONSORED-Hotspots-FLOPS-and
存取 L1 cache 需 4 個 clock cycles
存取 L2 cache 需 10 個 clock cycles
存取 L3 cache 需 75 個 clock cycles
存取外部 RAM 需數百個 clock cycles
(在 1980 年代 IBM PC 剛問世的那時,CPU 存取 RAM 只需數個 clock cycle)
換句話說,記憶體存取 cache hit 與 miss 與否,會大幅影響系統效能
在 game design 中,經常用到 4x4 的轉換矩陣
若以單精度浮點數來看 (4 bytes),一個 4x4 轉換矩陣佔 64 bytes
以現在 Intel CPU 的 L2 cache 的 line width 通常是 128 bytes
換句話說,一個 L2 cache line 只裝了兩個 4x4 矩陣
當一大堆物件需進行矩陣相乘的運算 (在 game design 很常見)
若以 OOP 的寫法 (C++),可能會寫成以下的方式 (簡化自投影片中的例子)
void functionA() {
for (i = 0; i < N; i++) {
objArray[i].Transform(parentTransform);
}
}
inline void Object::Transform(Matrix &parentTransform) {
this->m_worldTransform = parentTransform * this->m_Transform;
}
其中 m_worldTransform 與 m_Transform 這兩個 member variable
均為 64-byte 的 4x4 矩陣
因為 objArray[i] 這個物件中,除了 m_worldTransform 與 m_Transform 兩個矩陣
還包含其它變數,virtual table pointer 等等其它東西
所以一個物件在 L2 cache 中,可能佔據 2 個或以上的 cache line
在執行上述的迴圈時,以投影片中的演示發現
每執行一次的矩陣相乘,會發生至少二至三次以上 L2 cache miss
若改變寫法,將 m_worldTransform 與 m_Transform 從物件中拆出來
使用單純的陣列存放,如下:
for (i = 0; i < N; i++) {
worldTransformArray[i] = parentTransform * transformArray[i];
}
這種做法是將同質性的資料放在一起
而原本同一個物件的 m_worldTransform 與 m_Transform 被拆放至兩個陣列中
以陣列本身作 memory locality
(這種技巧,若有接觸 GPU programming 的人,應該滿熟悉)
以 OOP 的概念來看,這已經破壞 Data Encapsulation
但這樣的做法,卻可以降低 L2 cache miss rate 至每矩陣相乘 1 次 cache miss
在 N 很大時,改用矩陣的寫法,比起使用純 OOP 的寫法,效能將會大幅提升
----------
加上投影片中所演示的其它部分,均指出在 game design 時
有些地方必須避開 OOP 的實作方式,會比較洽當
----------
是否使用 OOP,我自己的信條時,直接回歸至實務面的考量
適合的地方用之,不適合的地方避之
一味的使用或是一味的不使用,都不是件好事
當然平常 OOP 帶來的好處不少,且配合 IDE tool 亦會使開發更為便利
但在特殊場合中,比如投影片中所提的 game design
這時反而要故意破壞一般 OOP 的寫法
尤其是 performance insentive 的部分,更須檢討這些地方是否適合使用 OOP
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 114.32.58.129
推
02/23 03:57, , 1F
02/23 03:57, 1F
會知道這個綽號的,大概是天寶年間的活躍人物
不過您的 ID,我一時猜不出來倒底是哪位老同學老朋友
上 FB 搜尋我的中文名字加我吧
→
02/23 10:03, , 2F
02/23 10:03, 2F
→
02/23 10:03, , 3F
02/23 10:03, 3F
→
02/23 10:03, , 4F
02/23 10:03, 4F
它的重點不在於 array 是不是要以 array pool 或 singleton 包裝
改良後的 implementation 是不是可以再包裝成另外的物件不是投影片的重點
這篇的重點在於,以 OOP 其中一個核心概念:Data Encapsulation
像 m_worldTransform 與 m_Transform,既然是 Object 的屬性,要包在 Object 裡
將它們從 class Object 拆出去的做法,馬上就違反 OOP 的天條
但這樣包進去 class Object 裡,會造成 performance impact
而且會使硬體上的加速功能失效,諸如 cache prefetch 的機制
在投影片中,如果資料好好規劃,performance 可以相差四、五倍以上
以 game design 這個領域,這可是生與死的巨大差別!!!
※ 編輯: mgtsai 來自: 122.116.84.29 (02/23 10:41)
推
02/23 11:06, , 5F
02/23 11:06, 5F
→
02/23 11:06, , 6F
02/23 11:06, 6F
→
02/23 11:20, , 7F
02/23 11:20, 7F
→
02/23 11:23, , 8F
02/23 11:23, 8F
→
02/23 11:24, , 9F
02/23 11:24, 9F
→
02/23 11:25, , 10F
02/23 11:25, 10F
→
02/23 11:26, , 11F
02/23 11:26, 11F
→
02/23 11:28, , 12F
02/23 11:28, 12F
→
02/23 13:36, , 13F
02/23 13:36, 13F
→
02/23 13:37, , 14F
02/23 13:37, 14F
→
02/23 13:38, , 15F
02/23 13:38, 15F
→
02/23 13:40, , 16F
02/23 13:40, 16F
→
02/23 16:26, , 17F
02/23 16:26, 17F
→
02/23 16:27, , 18F
02/23 16:27, 18F
→
02/23 16:28, , 19F
02/23 16:28, 19F
→
02/23 16:29, , 20F
02/23 16:29, 20F
→
02/23 16:29, , 21F
02/23 16:29, 21F
→
02/23 16:30, , 22F
02/23 16:30, 22F
→
02/23 16:30, , 23F
02/23 16:30, 23F
→
02/23 16:30, , 24F
02/23 16:30, 24F
→
02/23 16:31, , 25F
02/23 16:31, 25F
→
02/23 16:32, , 26F
02/23 16:32, 26F
推
02/23 18:00, , 27F
02/23 18:00, 27F
→
02/23 18:02, , 28F
02/23 18:02, 28F
→
02/23 18:05, , 29F
02/23 18:05, 29F
→
02/23 19:50, , 30F
02/23 19:50, 30F
→
02/23 19:52, , 31F
02/23 19:52, 31F
→
02/23 19:59, , 32F
02/23 19:59, 32F
→
02/23 20:01, , 33F
02/23 20:01, 33F
→
02/23 20:03, , 34F
02/23 20:03, 34F
→
02/23 21:38, , 35F
02/23 21:38, 35F
→
02/24 01:42, , 36F
02/24 01:42, 36F
→
02/24 01:42, , 37F
02/24 01:42, 37F
推
02/24 01:48, , 38F
02/24 01:48, 38F
推
02/24 01:54, , 39F
02/24 01:54, 39F
→
02/24 20:22, , 40F
02/24 20:22, 40F
→
02/24 22:34, , 41F
02/24 22:34, 41F
→
02/24 22:35, , 42F
02/24 22:35, 42F
→
02/24 22:36, , 43F
02/24 22:36, 43F
→
02/24 22:37, , 44F
02/24 22:37, 44F
→
02/24 22:38, , 45F
02/24 22:38, 45F
→
02/24 22:44, , 46F
02/24 22:44, 46F
→
02/24 22:45, , 47F
02/24 22:45, 47F
→
02/25 08:57, , 48F
02/25 08:57, 48F
→
02/25 08:58, , 49F
02/25 08:58, 49F
→
02/25 11:59, , 50F
02/25 11:59, 50F
→
02/25 12:01, , 51F
02/25 12:01, 51F
→
02/25 12:01, , 52F
02/25 12:01, 52F
→
02/25 12:02, , 53F
02/25 12:02, 53F
→
02/25 12:51, , 54F
02/25 12:51, 54F
→
02/25 12:52, , 55F
02/25 12:52, 55F
→
02/25 12:58, , 56F
02/25 12:58, 56F
→
02/25 12:58, , 57F
02/25 12:58, 57F
→
02/25 12:59, , 58F
02/25 12:59, 58F
→
02/25 13:07, , 59F
02/25 13:07, 59F
→
02/25 13:07, , 60F
02/25 13:07, 60F
→
02/25 13:07, , 61F
02/25 13:07, 61F
→
02/25 13:33, , 62F
02/25 13:33, 62F
→
02/25 15:01, , 63F
02/25 15:01, 63F
→
02/25 15:02, , 64F
02/25 15:02, 64F
→
02/25 15:03, , 65F
02/25 15:03, 65F
→
02/25 15:07, , 66F
02/25 15:07, 66F
→
02/25 15:07, , 67F
02/25 15:07, 67F
→
02/25 17:47, , 68F
02/25 17:47, 68F
→
02/25 17:48, , 69F
02/25 17:48, 69F
→
02/25 17:48, , 70F
02/25 17:48, 70F
→
02/25 18:45, , 71F
02/25 18:45, 71F
→
02/25 18:51, , 72F
02/25 18:51, 72F
→
02/25 21:11, , 73F
02/25 21:11, 73F
→
02/25 21:12, , 74F
02/25 21:12, 74F
→
02/25 21:12, , 75F
02/25 21:12, 75F
→
02/25 21:16, , 76F
02/25 21:16, 76F
→
02/25 21:16, , 77F
02/25 21:16, 77F
→
02/25 21:17, , 78F
02/25 21:17, 78F
→
02/25 21:22, , 79F
02/25 21:22, 79F
→
02/25 21:24, , 80F
02/25 21:24, 80F
→
02/25 21:24, , 81F
02/25 21:24, 81F
→
02/25 21:31, , 82F
02/25 21:31, 82F
→
02/25 21:31, , 83F
02/25 21:31, 83F
→
02/25 22:28, , 84F
02/25 22:28, 84F
→
02/25 22:28, , 85F
02/25 22:28, 85F
→
02/25 22:31, , 86F
02/25 22:31, 86F
→
02/25 22:31, , 87F
02/25 22:31, 87F
推
02/27 08:35, , 88F
02/27 08:35, 88F
討論串 (同標題文章)