看板 Soft_Job 關於我們 聯絡資訊
※ 引述《Aurim (Who cares?)》之銘言: : ※ 引述《lgd1008 (lgd1008)》之銘言: : : 不要只把 VM, GC 算進 overhead, 而不同時考慮他們可能對效能產生的幫助, : 請試舉一例VM/GC對整體效能有幫助的例子。 : : CPU的指令己是VC++執行時的全部, 但並非 .net, Java執行時的全部 : 這句話在我聽來相當不切實際,莫非.net/java不需要CPU? : 凡是以CPU執行的,最後都是要用CPU的指令去跑的, : 中間多做事情只是多花時間的,跑愈多指令去做一件事只是用更多時間去完成那事。 : 就假設所有指令都可以在單個clock內完成的RISC來說,執行每個指令都只要1 cycle, : 所有演算法的時間複雜度直接與跑了多少個CPU指令在統計上就是絕對正相關。 : 你可以爭論說,GC可以在某種程度上改善你跑的演算法花在釋放記憶體的代價; : 但是整體觀之,那不過是朝三暮四的效果,該做的事情最後還是都要做,而且付出了 : 更大的效能代價去做,因為你還要多花時間去爬垃圾堆,看是不是該清垃圾了, : 而不是在垃圾丟出來時就馬上清掉。 : IKVM.net的作者都會常常關注Java VM JIT生出來的code與他的IKVM將Java bytecode : 轉成IL code再生成原生code後的指令數差距、對CPU管線利用率的影響了。 VM 本來就只是為了 portable, 至於到底是 JIT 還是 precompile 效果好, 這很不一定, 記憶體小的情況下, 甚至 interpreter 最好, FORTH 時代就有很多例子 GC 把記憶體物件化, 其實很容易平行處理, 甚至專門有硬體來進行 GC, 所以 GC 在實做上可以視為幾乎沒有效能代價, 卻有重大方便, 唯一不方便的是 destructor 不確定何時會啟動, 讓寫 C++ 的人不習慣 要追求極致效能, 就要拋棄系統的記憶體管理, 自己配置一大塊來分, 大型的 C/C++ 程式多半都這麼做了 : : 會拿看起來 VM, GC 是 overhead 的情況去看 Java, .net : : 那怎麼不拿非 VM, GC 存在不可的情況去看 VC++ 呢? : : 如果你真的完全不想這種可能性, 應該早就值疑上篇測試的結果作假了.. : 前面有人留言說愈快的CPU上那overhead應該愈低,我說在單純只是時脈提升的情形下, : 因為要跑的CPU指令數沒變,總cycle數也不會因為CPU用比較快的clock跑就會減少, : 那overhead percentagle還是沒變-本來是5%的就還是5%,本來是30%的就還是30%, : 除非JIT的最佳化做得更好,減少產生出來的指令數,用跑更快的指令排列去應用CPU的 : 管線最佳化,不然在單純CPU時脈提升的情形下,這些overhead的比例根本不會降,只會 : 讓實質的絕對差距愈拉愈大-直接編譯成原生碼的軟體可以利用這愈拉愈大的差距來做 : 更多事。 : 表面上,你看到VM跑的code與編譯為原生碼程式間的執行時間差隨著機器變快而減少, : 可是能處理的工作量的增長是如何呢? : 為了方便計算,假設本來VM生出來的code跑一圈要2M cycle,編譯成原生碼跑一圈只要 : 1M cycle。在100MHz的CPU上執行時間比會是兩秒比一秒,在200MHz的CPU上會變成一秒 : 比半秒。你可以說,使用VM的語言與原生碼語言間的差距縮小了一倍,從一秒縮成半秒 : ;我也可以說,可是一樣的code在一秒內能處理的工作量差距拉大了,從本來的0.5件 : 比一件,變成一件比兩件,中間差距從0.5拉大到1。當CPU clock拉高到1GHz,這一秒內 : 可完成工作量的差距已經從100MHz時的0.5件工作拉大到1GHz的5件,中間差4.5件工作。 : 如果18個月後CPU時脈提高成2GHz,兩份code每秒完成工作量的差距會拉大到10件。 : 因為現實上看起來差距好像沒那麼大,所以對VM有著美夢的人還在繼續作夢。 : 5%的差距看起來好像沒什麼,可是已經足夠原生碼的新版程式多做一堆小動作了。 : 當這差距拉大到10%、20%、30%,又是個什麼樣的境地?你以為VM慢的真的只在IO與GC? : iOS device用的CPU現在確實是還不太快,Android device用的CPU也沒比較好到哪去。 : 以後CPU clock會繼續往上拉,也許VM派的人會想:這中間時間差距不是縮小了嗎? : 可是當我們回到現實看單位時間內能做的事情,原生碼能負擔的工作量成長比VM能做 : 的工作量成長要快,所以在許多小地方可以提供更好的表現。 : 那考慮CPU架構改善的場合,情形又是如何? : 如果JIT沒與時俱進的配合CPU的改良來生出最佳化的code,根本享受不到這方面的好處。 : C/C++編譯器都得改版來加入配合新CPU特性的最佳化功能了。 : 大家一樣是用ARM based CPU,各家做CPU的巧妙各有不同,Java JIT真能對各家ARM : based CPU應用各CPU獨家的最佳化技巧?指令怎麼排列的執行速度都有差了,還要一家 : 一種排法,慢慢等比較快。 : .NET起碼還可以在安裝時先把IL code executable編譯一遍存一份native code image, : 離線的最佳化可以做更多事,Windows on ARM也大可真的配合各家CPU來做這種時候的 : 最佳化。Java哪時候要照著玩這招? IL 跟 java 根本是一樣的 stack machine, 你比較的只是 M$ 跟某些 Java 廠商的 compiler, 而不是兩種技術的優劣, M$ compiler 好不好, 看 WM 跟 android 比較就知道, 不多說 先 compile 一份 native code 就會拖慢安裝時間, 還會占好幾倍空間, browser 明顯不太適用, 說不定 user 一輩子只用一次這程式, 而 java 也一樣有先 compile 的作法存在, 只是手機記憶體有限, 所以沒有人使用這個方法, 光 byte code 就塞不夠了還管 native code, 尤其 RISC 的 native code 一般是 x86 兩倍大 離線最佳化一定比不過即時, 沒跑過怎知道哪個變數才是熱點, 哪一種作法好, 只是執行效能跟 compile/profile 代價的數字遊戲 : 要不要把GPU與其他平行處理單元再考慮進來? GPU 的 code 都是 JIT 的, 除非你綁死某一款 GPU, 不然準備幾十種 precompile 太誇張 -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 122.116.218.88