Re: [分享] 面向對象編程從骨子裡就有問題

看板Soft_Job作者時間11年前 (2013/02/23 02:39), 編輯推噓6(6082)
留言88則, 9人參與, 最新討論串5/12 (看更多)
※ 引述《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
兩光兄不玩physics&math la?
02/23 03:57, 1F
會知道這個綽號的,大概是天寶年間的活躍人物 不過您的 ID,我一時猜不出來倒底是哪位老同學老朋友 上 FB 搜尋我的中文名字加我吧

02/23 10:03, , 2F
將陣列拆出,是指將陣列宣告在class之外嗎?還是宣告成static
02/23 10:03, 2F

02/23 10:03, , 3F
這種作法跟做一個array pool,或是將array做成singleton有何
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
請問一下.... 用JAVA的應該不用管這個吧? JVM會搞定這些的
02/23 11:06, 5F

02/23 11:06, , 6F
樣子....
02/23 11:06, 6F

02/23 11:20, , 7F
個人認為這例子是物件責作規劃的問題, OOP也不是說一種問題
02/23 11:20, 7F

02/23 11:23, , 8F
而光從m_worldTransform從名稱上來看,也不太像是一個object
02/23 11:23, 8F

02/23 11:24, , 9F
應有的屬性. 我個人是認為,設計是一個整體面向的東西,光以
02/23 11:24, 9F

02/23 11:25, , 10F
部分的設計來討論OOP的概念的極限,其實很難有一個明確結果.
02/23 11:25, 10F

02/23 11:26, , 11F
大概最後也是各說各話吧? - -a
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
不管用Java、C#或其它語言寫的~當然都要考慮建立一個物件
02/23 13:38, 15F

02/23 13:40, , 16F
所帶來的成本和影響~根本不必弄成物件的就不必過度設計...
02/23 13:40, 16F

02/23 16:26, , 17F
寫JAVA 不用管CACHE HIT? 當然你寫WEB AP 很多人一背子
02/23 16:26, 17F

02/23 16:27, , 18F
是連CACHE 是幹嘛的都不知道的, 因為真的不用管.
02/23 16:27, 18F

02/23 16:28, , 19F
JAVA/C# 有幾個人知道物件的成本? 有幾個寫JAVA/C# 的人
02/23 16:28, 19F

02/23 16:29, , 20F
需要知道這種細節的? 這不過就是經驗的問題.
02/23 16:29, 20F

02/23 16:29, , 21F
寫個WEB AP, 根本不會碰到這種東西. 當需要換行業時,
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
寫習慣JAVA 這一類有個INTERPRETER 的LANGUAGE 的人更少
02/23 16:31, 25F

02/23 16:32, , 26F
JAVA的天條更是多, 最有趣的就是, 一定要GET/SET 一下
02/23 16:32, 26F

02/23 18:00, , 27F
根據經驗,的確有些東西用OOP會降低performance
02/23 18:00, 27F

02/23 18:02, , 28F
只好改寫了....這的確是要經驗
02/23 18:02, 28F

02/23 18:05, , 29F
看哪些領域是不能用OO的方式寫,哪些可以.....
02/23 18:05, 29F

02/23 19:50, , 30F
web ap怎麼不會碰到問題?OO得不好~new得太過火~很容易就會
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
這種東西包在同一個大class裡面然後當成員操作就好了?
02/24 01:48, 38F

02/24 01:54, , 39F
喔..看懂了 因為會讀到class的其他東西
02/24 01:54, 39F

02/24 20:22, , 40F
投票看看"但起碼都要考慮怎麼設計吧"是否成立
02/24 20:22, 40F

02/24 22:34, , 41F
那還是要看怎麼投吧?以及投票的流程...做web ap的也不會老
02/24 22:34, 41F

02/24 22:35, , 42F
是做像簡單投票的東西~之前寫erp就看過整頁超過30個要填的
02/24 22:35, 42F

02/24 22:36, , 43F
資料~不少欄位的資料都需要去資料庫撈~這時如果有人的設計
02/24 22:36, 43F

02/24 22:37, , 44F
和寫法不好~new了一堆物件~for包了好幾層~物件生命週期沒
02/24 22:37, 44F

02/24 22:38, , 45F
在該結束的時候結束~甚至弄成static...那會有多慘???
02/24 22:38, 45F

02/24 22:44, , 46F
當然~一切都看需求~我在那家erp公司待的時候~觀念很差~也
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
廿顆CPU 的鳥系統,還不就照賣. JAVA 寫的呢.
02/25 08:58, 49F

02/25 11:59, , 50F
Andymei你知道這篇在討論的是硬體的cache嗎?你真的
02/25 11:59, 50F

02/25 12:01, , 51F
知道那是什麼嗎?你寫web真的有去考慮這些硬體層面的
02/25 12:01, 51F

02/25 12:01, , 52F
東西嗎?
02/25 12:01, 52F

02/25 12:02, , 53F
andymai
02/25 12:02, 53F

02/25 12:51, , 54F
我主要是回應那個OOP的天條~而且寫Java還是有heap和stack
02/25 12:51, 54F

02/25 12:52, , 55F
要考慮啊!設計不良~出現out of memory並不意外...
02/25 12:52, 55F

02/25 12:58, , 56F
難道寫web就可以什麼都不管~不考慮?那這樣誰都能寫出上萬
02/25 12:58, 56F

02/25 12:58, , 57F
人在線的網站了啊~所有的程式都用Java和C#開發就好了~幹嘛
02/25 12:58, 57F

02/25 12:59, , 58F
還一直要用C++寫???
02/25 12:59, 58F

02/25 13:07, , 59F
是啊,德國的交易所就是腦殘用C#寫了個交易系統, 而搞到
02/25 13:07, 59F

02/25 13:07, , 60F
又要換回C/C++ 寫的, 還號稱可以跟C/C++ 比的RSP TIME
02/25 13:07, 60F

02/25 13:07, , 61F
的呢
02/25 13:07, 61F

02/25 13:33, , 62F
VM 也用C#/JAVA寫? 哪ASSEMBLY 怎麼辨?
02/25 13:33, 62F

02/25 15:01, , 63F
Out of memory是潛在memory leak或是使用過多memory
02/25 15:01, 63F

02/25 15:02, , 64F
你真的知道本文在討論cache嗎?你真的知道cache嗎
02/25 15:02, 64F

02/25 15:03, , 65F
先去看看computer architecture再來討論行嗎
02/25 15:03, 65F

02/25 15:07, , 66F
本篇, 怎麼看都是在說, OOP不夠好的地方, 以CACHE為例
02/25 15:07, 66F

02/25 15:07, , 67F
不能叫討論CACHE.
02/25 15:07, 67F

02/25 17:47, , 68F
我可沒說換成C#/Java來寫會比較好唷...而且都說過了~我沒
02/25 17:47, 68F

02/25 17:48, , 69F
有針對cache在回啊...都說了是針對OOP的天條在回~要講幾次
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
還是你沒搞清楚OOP.
02/25 21:12, 74F

02/25 21:12, , 75F
特別是JAVA, 天條特多.
02/25 21:12, 75F

02/25 21:16, , 76F
=.= so what? 沒人逼你遵守~不是嗎? 明明要OO到什麼程度~
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
像原PO舉例說的把屬性拆出去是"違反"的做法~個人就認為要
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
寫C 不就好了.
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
話說回來~剛剛才看到其實原PO的結論就是我同意的結論~這樣
02/25 22:31, 86F

02/25 22:31, , 87F
看來算是我"厚話"了 XD
02/25 22:31, 87F

02/27 08:35, , 88F
感謝分享
02/27 08:35, 88F
文章代碼(AID): #1H9xj5Uf (Soft_Job)
討論串 (同標題文章)
本文引述了以下文章的的內容:
以下文章回應了本文 (最舊先):
完整討論串 (本文為第 5 之 12 篇):
文章代碼(AID): #1H9xj5Uf (Soft_Job)