看板 Soft_Job 關於我們 聯絡資訊
※ 引述《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
Ntst0:兩光兄不玩physics&math la? 02/23 03:57
會知道這個綽號的,大概是天寶年間的活躍人物 不過您的 ID,我一時猜不出來倒底是哪位老同學老朋友 上 FB 搜尋我的中文名字加我吧
atst2:將陣列拆出,是指將陣列宣告在class之外嗎?還是宣告成static 02/23 10:03
atst2:這種作法跟做一個array pool,或是將array做成singleton有何 02/23 10:03
atst2:差異嗎? 02/23 10:03
它的重點不在於 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)
LaPass:請問一下.... 用JAVA的應該不用管這個吧? JVM會搞定這些的 02/23 11:06
LaPass:樣子.... 02/23 11:06
atst2:個人認為這例子是物件責作規劃的問題, OOP也不是說一種問題 02/23 11:20
atst2:而光從m_worldTransform從名稱上來看,也不太像是一個object 02/23 11:23
atst2:應有的屬性. 我個人是認為,設計是一個整體面向的東西,光以 02/23 11:24
atst2:部分的設計來討論OOP的概念的極限,其實很難有一個明確結果. 02/23 11:25
atst2:大概最後也是各說各話吧? - -a 02/23 11:26
atst2:補充第二行....一種問題不會只有一種設計.. 02/23 11:28
andymai:天條???為什麼說得好像十惡不赦一樣???怎麼寫是自己決定或 02/23 13:36
andymai:大家討論的~不是嗎?幹嘛硬逼自己遵守不合時宜的規則??? 02/23 13:37
andymai:不管用Java、C#或其它語言寫的~當然都要考慮建立一個物件 02/23 13:38
andymai:所帶來的成本和影響~根本不必弄成物件的就不必過度設計... 02/23 13:40
Lordaeron:寫JAVA 不用管CACHE HIT? 當然你寫WEB AP 很多人一背子 02/23 16:26
Lordaeron:是連CACHE 是幹嘛的都不知道的, 因為真的不用管. 02/23 16:27
Lordaeron:JAVA/C# 有幾個人知道物件的成本? 有幾個寫JAVA/C# 的人 02/23 16:28
Lordaeron:需要知道這種細節的? 這不過就是經驗的問題. 02/23 16:29
Lordaeron:寫個WEB AP, 根本不會碰到這種東西. 當需要換行業時, 02/23 16:29
Lordaeron:會遇到, 才會出問題. 02/23 16:30
Lordaeron:要說這是資工的基礎, 基本上可以說是. 02/23 16:30
Lordaeron:但要說多少人會想到, 基本上很少. 02/23 16:30
Lordaeron:寫習慣JAVA 這一類有個INTERPRETER 的LANGUAGE 的人更少 02/23 16:31
Lordaeron:JAVA的天條更是多, 最有趣的就是, 一定要GET/SET 一下 02/23 16:32
KASUGAOSAKA:根據經驗,的確有些東西用OOP會降低performance 02/23 18:00
KASUGAOSAKA:只好改寫了....這的確是要經驗 02/23 18:02
KASUGAOSAKA:看哪些領域是不能用OO的方式寫,哪些可以..... 02/23 18:05
andymai:web ap怎麼不會碰到問題?OO得不好~new得太過火~很容易就會 02/23 19:50
andymai:讓網站撐不住~沒有經驗很快就會被打臉~強迫學習改進... 02/23 19:52
andymai:當然~容不容易碰到問題還是要看需求~很多人不會遇到~但也 02/23 19:59
andymai:很多人會遇到~也是很多人都是先設計實做完~不行了再改進 02/23 20:01
andymai:不必精算成本~但起碼都要考慮怎麼設計吧... 02/23 20:03
Lordaeron:考慮? 你可以作個投票來看看囉. 02/23 21:38
andymai:@@ 不懂作投票要看什麼?看怎麼設計?我已經有寫過很簡單的 02/24 01:42
andymai:信件系統了... 02/24 01:42
amozartea:這種東西包在同一個大class裡面然後當成員操作就好了? 02/24 01:48
amozartea:喔..看懂了 因為會讀到class的其他東西 02/24 01:54
Lordaeron:投票看看"但起碼都要考慮怎麼設計吧"是否成立 02/24 20:22
andymai:那還是要看怎麼投吧?以及投票的流程...做web ap的也不會老 02/24 22:34
andymai:是做像簡單投票的東西~之前寫erp就看過整頁超過30個要填的 02/24 22:35
andymai:資料~不少欄位的資料都需要去資料庫撈~這時如果有人的設計 02/24 22:36
andymai:和寫法不好~new了一堆物件~for包了好幾層~物件生命週期沒 02/24 22:37
andymai:在該結束的時候結束~甚至弄成static...那會有多慘??? 02/24 22:38
andymai:當然~一切都看需求~我在那家erp公司待的時候~觀念很差~也 02/24 22:44
andymai:沒做過什麼設計和效能的改善...剛剛的例子是別的部門的... 02/24 22:45
Lordaeron:很慘的東西, 很多, 賣銀行的系統,動不動就吃掉十幾 02/25 08:57
Lordaeron:廿顆CPU 的鳥系統,還不就照賣. JAVA 寫的呢. 02/25 08:58
king19880326:Andymei你知道這篇在討論的是硬體的cache嗎?你真的 02/25 11:59
king19880326:知道那是什麼嗎?你寫web真的有去考慮這些硬體層面的 02/25 12:01
king19880326:東西嗎? 02/25 12:01
king19880326:andymai 02/25 12:02
andymai:我主要是回應那個OOP的天條~而且寫Java還是有heap和stack 02/25 12:51
andymai:要考慮啊!設計不良~出現out of memory並不意外... 02/25 12:52
andymai:難道寫web就可以什麼都不管~不考慮?那這樣誰都能寫出上萬 02/25 12:58
andymai:人在線的網站了啊~所有的程式都用Java和C#開發就好了~幹嘛 02/25 12:58
andymai:還一直要用C++寫??? 02/25 12:59
Lordaeron:是啊,德國的交易所就是腦殘用C#寫了個交易系統, 而搞到 02/25 13:07
Lordaeron:又要換回C/C++ 寫的, 還號稱可以跟C/C++ 比的RSP TIME 02/25 13:07
Lordaeron:的呢 02/25 13:07
Lordaeron:VM 也用C#/JAVA寫? 哪ASSEMBLY 怎麼辨? 02/25 13:33
king19880326:Out of memory是潛在memory leak或是使用過多memory 02/25 15:01
king19880326:你真的知道本文在討論cache嗎?你真的知道cache嗎 02/25 15:02
king19880326:先去看看computer architecture再來討論行嗎 02/25 15:03
Lordaeron:本篇, 怎麼看都是在說, OOP不夠好的地方, 以CACHE為例 02/25 15:07
Lordaeron:不能叫討論CACHE. 02/25 15:07
andymai:我可沒說換成C#/Java來寫會比較好唷...而且都說過了~我沒 02/25 17:47
andymai:有針對cache在回啊...都說了是針對OOP的天條在回~要講幾次 02/25 17:48
andymai:?如果要我另開文章就免了...謝謝... 02/25 17:48
Lordaeron:天條就是有問題, 你也無法辯, 就是這樣子. 02/25 18:45
andymai:=.=我要講的就是根本"沒有天條"啊...要不要再看一下我講啥 02/25 18:51
Lordaeron:根本就一堆天條, 你要不要了解一下呢. 02/25 21:11
Lordaeron:還是你沒搞清楚OOP. 02/25 21:12
Lordaeron:特別是JAVA, 天條特多. 02/25 21:12
andymai:=.= so what? 沒人逼你遵守~不是嗎? 明明要OO到什麼程度~ 02/25 21:16
andymai:要怎麼設計都是人自己決定的~結果用的人卻反過頭來說它不 02/25 21:16
andymai:好?這哪招? 02/25 21:17
andymai:像原PO舉例說的把屬性拆出去是"違反"的做法~個人就認為要 02/25 21:22
andymai:看狀況~為了效能把它拆出去又怎樣?而且也許該想想"它是不 02/25 21:24
andymai:是本來就該這樣設計?"、"這物件一定得長這樣?" 02/25 21:24
Lordaeron:會有人拿出來討論, 就是因為這是天條. 否則有什麼好講的 02/25 21:31
Lordaeron:寫C 不就好了. 02/25 21:31
andymai:如果都沒有重新思考的餘地~喜歡被自己一開始的思想挶限起~ 02/25 22:28
andymai:來~的確是沒辦法~解鈴還需繫鈴人啊... 02/25 22:28
andymai:話說回來~剛剛才看到其實原PO的結論就是我同意的結論~這樣 02/25 22:31
andymai:看來算是我"厚話"了 XD 02/25 22:31
foxkid:感謝分享 02/27 08:35