看板 C_and_CPP 關於我們 聯絡資訊
Unity開發元老抨擊:C++ 20新功能造成編譯緩慢與偵錯建置效能低落 2019-01-03發表 新聞連結 https://www.ithome.com.tw/news/127973 (我對C++不熟悉,只是看到相關新聞轉貼) C++ 20即將加入的新功能Ranges,不只造成編譯速度緩慢,偵錯建置的執行效能還是簡單 版C++的150倍。 負責Unity繪圖引擎架構與發展的元老工程師Aras Pranckevius,在個人部落格發表不 看好C++ 20新功能Ranges的文章,而其在推特上的貼文也引來許多遊戲開發工程師表達相 同的感受。他提到,C++的編譯時間與偵錯建置(Debug Build)效能非常重要,但是C++ 20的新功能Ranges卻讓這兩者都大幅增加。 11月ISO C++委員會在聖地亞哥召開了有史以來最大規模的會議,就C++ 20的語言更新草 案進行討論,而決議之一便是決定加入Ranges概念。Ranges是即將在C++ 20加入的新語法 功能,Ranges用來幫助操作範圍概念,能夠讓開發者簡單的迭代具有開始和結束範圍,並 回傳行為類似迭代器的物件。Ranges能夠讓語法更為簡潔,使程式碼閱讀者不再需要自己 解析複雜的for迴圈邏輯。 而主推Ranges和Concepts進入標準函式庫的Eric Nieble,在自己的部落格發表標題為 Standard Ranges的文章,然而卻在Aras Pranckevius發表評論之後,引來了部分遊戲 開發者的討論,多數表達了反對意見。 Aras Pranckevius使用目前最佳近似實作,由Eric Nieble撰寫的range-v3,與簡單版 C++進行比較,他指出,C++ 20可能的問題至少有兩個,編譯時間與執行效能。他以Eric Nieble在自己部落格解釋Ranges功能的畢氏三元數為例,以使用Ranges的C++編譯程式碼 ,編譯時間長達2.92秒,比簡單版C++的0.064秒還要多2.85秒,他表示,現代的CPU可以 在3秒的時間,進行很大量的操作,像是以Clang在偵錯模式中編譯完整資料庫引擎SQLite 只要0.9秒,他質疑,編譯畢氏三元數的5行程式碼,卻需要編譯整個資料庫引擎的3倍時 間。 Aras Pranckevius指出,編譯時間是編譯大型C++程式碼庫痛苦的來源,他隨意列舉 Chromium、Clang/LLVM或UE4專案,都能讓開發者輕易的體驗這件事,他指出,編譯時間 就是一個C++待解決的大問題,而且應該在列表中排名之一,但是整個C++社群卻假裝這不 是個問題。 由於在每個C++版本都會有更多的內容被放進標頭檔中,而且不像是C只在標頭檔案放入結 構聲明或是函式原型,C++會把整個模板化的類別和函式都加入。range-v3是一個大小 1.8MB的程式標頭檔,而且即便預編譯標頭檔,也只省下了0.7秒,整個編譯時間仍然長達 2.24秒,比簡單版C++仍然長2.1秒。 另外,Aras Pranckevius也提到,非最佳化建置效能也是非常重要的,在畢氏三元數 的例子中,擁有Ranges的C++執行時間為300毫秒,而簡單版的C++卻只要2毫秒,也就是說 執行效能慢了150倍,他認為,執行時間多2到3倍可以接受,慢10倍以上可能代表無法使 用,而有Ranges的C++卻是百倍以上。 執行效能對於遊戲程式來說非常重要,Aras Pranckevius表示,或許在部分應用偵錯 模式中慢10或100倍的時間,只是比較擾人,但是在遊戲中,當每秒只有2個影格,則已經 不是感覺上的問題,而是從根本上無法達到玩遊戲的體驗。即便建置最佳化後的執行效能 與簡單版本相同,但Aras Pranckevius提到,要對最佳化的程式碼偵錯非常困難,這 增加了工作難度。 相較之下,以C#實作畢氏三元數,使用Mono編譯器編譯需要0.2秒,而簡單版的C#則是 0.17秒,兩者相去不遠。Aras Pranckevius認為,雖然C++ 20被稱為現代C++,但事實 上這些變化,並沒有因為是「現代」而變得更好,大多數遊戲開發人員都還停留在C++ 11 、14或是17的版本,無論C++ 20增加了什麼新功能,編譯時間與偵錯建置效能太差就毫無 用武之地。 儘管Aras Pranckevius的批評引起不少遊戲開發者的聲援贊同,但range設計目的是為 了簡化複雜的C++程式碼,超多行數的大型程式碼是否會如簡單幾行的畢氏三元數程式一 樣,遭遇到同樣嚴重的效能問題,Aras Pranckevius則沒有進一步舉例實測。 -- ※ 發信站: 批踢踢實業坊(ptt.cc), 來自: 118.167.172.123 ※ 文章網址: https://www.ptt.cc/bbs/C_and_CPP/M.1546668804.A.5ED.html
eye5002003: 看來要學著在release模式下開發程式了 01/06 18:17
chuegou: 不太理解為什麼會影響到編譯結果的執行效率而且還是變慢 01/06 23:49
poyenc: 因為 cmcstl2 乃至 range-v3 裡的 view 都是靠一層層的 01/07 00:18
poyenc: wrapper 來達成目的, 所以如果編譯的時候沒有嘗試把這些間 01/07 00:19
poyenc: 接層拿掉 (debug build), 執行變慢是一定的 01/07 00:20
poyenc: 不過因為 Eric Nieble 和 Casey Carter 開發主要都專注在 01/07 00:22
poyenc: "給予編譯器更多的機會最佳化" 所以 debug build 是暫時無 01/07 00:23
poyenc: 解的 01/07 00:24
poyenc: 更正人名是 Eric Niebler 01/07 02:23
tinlans: 這東西要質疑的是做編譯器的廠商有沒有好好實作吧 01/12 09:27