安卓系統下luajit性能問題


luajit本身是沒有問題的,但是在cocos項目中可能由於初始化內存無法分配導致有問題了,直接的證據就是jit.off()狀態下比jit.on()狀態下明顯效率更高。

這里有篇文字對此進行了說明
http://www.cnblogs.com/zwywilliam/p/5999980.html18

3.1可供代碼執行的內存空間被耗盡->要么放棄jit,要么修改luajit的代碼

要jit,就要編譯出機器碼,放到特定的內存空間。但是arm有一個限制,就是跳轉指令只能跳轉前后32MB的空間,這導致了一個巨大的問題:luajit生成的代碼要保證在一個連續的64MB空間內,如果這個空間被其他東西占用了,luajit就會分配不出用於jit的內存,而目前luajit會瘋狂重復嘗試編譯,最后導致性能處於癱瘓的狀態。
雖然網上有一些不修改luajit的方案(http://www.freelists.org/post/luajit/Performance-degraded-significantly-when-enabling-JIT,9),在lua中調用luajit的jit.opt的api嘗試將內存空間分配給luajit,但根據我們的測試,在unity上這樣做仍然無法保證所有機器上能夠不出問題,因為這些方案的原理要搶在這些內存空間被用於其他用途前全部先分配給luajit,但是ulua可以運行的時候已經是程序初始化非常后期的階段,這個時候眾多的unity初始化流程可能早已耗光了這塊內存空間。相反cocos2dx這個問題並不多見,因為luajit運行早,有很大的機會提前搶占內存空間。
無論從代碼看還是根據我們的測試以及luajit maillist的反饋來看,這個問題早在2.0.x就存在,更換2.1.0依然無法解決,我們建議,如果項目想要使用jit模式,需要在android工程的Activity入口中就加載luajit,做好內存分配,然后將這個luasate傳遞給unity使用。如果不願意趟這個麻煩,那可以根據項目實際測試的情況,考慮禁用jit模式。一般來說,lua代碼越少,遇到這個問題的可能性越低。

3.2寄存器分配失敗->減少local變量、避免過深的調用層次

很不幸的一點是,arm中可用的寄存器比x86少。luajit為了速度,會盡可能用寄存器存儲local變量,但是如果local變量太多,寄存器不夠用,目前jit的做法是:放棄治療(有興趣可以看看源碼中asm_head_side函數的注釋)。因此,我們能做的,只有按照官方優化指引說的,避免過多的local變量,或者通過do end來限制local變量的生命周期。

3.3調用c函數的代碼無法jit->使用ffi,或者使用2.1.0beta2

這里要提醒一點,調用c#,本質也是調用c,所以只要調用c#導出,都是一樣的。而這些代碼是無法jit化的,但是luajit有一個利器,叫ffi,使用了ffi導出的c函數在調用的時候是可以jit化的。
另外,2.1.0beta2開始正式引入了trace stitch,可以將調用c的lua代碼獨立起來,將其他可以jit的代碼jit掉,不過根據作者的說法,這個優化效果依然有限。

3.4jit遇到不支持的字節碼->少用for in pairs,少用字符串連接

有非常多bytecode或者內部庫調用是無法jit化的,最典型就是for in pairs,以及字符串連接符(2.1.0開始支持jit)。
具體可以看http://wiki.luajit.org/NYI,只要不是標記yes或者2.1的代碼,就不要過多使用。

4.怎么知道自己的代碼有沒有jit失敗?使用v.lua

完整的luajit的exe版本都會帶一個jit目錄,下面有大量luajit的工具,其中有一個v.lua,這是luajit verbose mode(另外還有一個很重要的叫p.lua,luajit profiler,后面會提到),可以追蹤luajit運行過程中的一些細節,其中就可以幫你追蹤jit失敗的情況。
local verbo = require("jit.v")
verbo.start()
當你看到以下錯誤的時候,說明你遇到了jit失敗
failed to allocate mcode memory,對應錯誤3.1
NYI: register coalescing too complex,對應錯誤3.2
NYI: C function,對應錯誤3.3(這個錯誤在2.1.0beta2中已經移除,因為有trace stitch)
NYI: bytecode,對應錯誤3.4
這在luajit.exe下使用會很正常,但要在unity下用上需要修改v.lua的代碼,把所有out:write輸出導向到Debug.Log里頭。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM