2014-10-30 54 views
3

有誰知道齒軌VM的菲羅和佳樂是否能夠優化掉簡單的可變間接與存取訪問是這樣的:齒軌VM和間接變量訪問

SomeClass>>someProperty 
    ^someProperty 
SomeClass>>someSecondProperty 
    ^someSecondProperty 

,只是返回一個實例變量,從而使這樣的方法:

SomeClass>>someMethod 
    ^self someProperty doWith: self someSecondProperty 

將不超過方式慢是這樣的:

SomeClass>>someMethod 
    ^someProperty doWith: someSecondProperty 

我做了一些基準測試,他們的速度似乎大致相當,但我很好奇,如果熟悉Cog的人知道肯定的話,因爲如果有差異(不管多麼微小),那麼可能會出現情況,一個是不合適的。

+1

該Pharo用戶組和郵件列表也可能是一個合適的地方要求。有很多活動。 – User 2014-10-30 20:00:32

+0

Yeap這個問題應該直接指向pharo-dev郵件列表和cog郵件列表,其中Clu後面的Eliot whos可以詳細回答 – Kilon 2014-10-31 10:49:07

回答

2

現在有一點成本,但它是如此之少,你不應該打擾。如果你想要性能,你願意改變代碼的其他部分,而不是實例變量訪問。

快速工作臺: 工作臺 ^ {你自己]長凳。 [self iv yourself] bench} =>#('52,400,000每秒''49,800,000每秒') 差異看起來並不那麼大。

一旦啓動並執行一次,區別在於除了獲取實例變量值之外,「自我iv」還執行內聯高速緩存檢查,cpu調用和cpu返回。調用和返回指令很可能是由cpu預計的,而不是真正執行的。所以這是關於內聯緩存檢查,這是一個非常便宜的操作。

開發中的內聯編譯器將添加的內容是,cpu調用和返回實際上將與內聯一起被刪除,這將涵蓋cpu未預期到的情況。此外,根據具體情況,內聯緩存檢查可能會也可能不會被移除。

有一些細節需要編譯爲本地代碼,這會佔用機器代碼區中的空間,這可能會增加機器代碼區垃圾收集的數量,但這比內聯高速緩存檢查開銷更爲軼事。

因此總之,現在的開銷非常小,但是將來開銷會減少。

Clement

+0

感謝您的真棒回答! – Manuel 2014-10-31 18:08:07

2

這是一個棘手的問題......我不知道確切的答案。但我可以幫助你學習如何通過一些線索自己檢查。

您需要在映像中加載VMMaker軟件包。在Pharo中,只需從網絡和github上下載所有內容,就可以建立這樣的映像。請參閱

然後,主要提示是剛剛返回實例變量的方法被編譯爲執行原語264 + inst var offset ...(例如,您將通過檢查Interval>>#first或任何其他簡單的inst var getter)

在傳統的解釋器VM中,這在Interpreter>>internalExecuteNewMethod中處理。
看起來像你支付方法查找的成本(一些緩存使這更便宜),但不是真正的方法激活。
我想它解釋了調試器不能進入這樣簡單的方法......但這不是真正的內聯。

在COG中,如果使用解釋器,則在StackInterpreter>>internalQuickPrimitiveResponse中也會發生同樣的情況。

至於JIT,這是由Cogit>>compilePrimitive處理,另見genQuickReturnInstVar的實現者。這並不適合內聯,但您可以看到生成的指令非常少。再次,我敢打賭,您通常不會支付查詢的代價,感謝所謂的多態內聯緩存(PIC)。

對於真正的內聯,我沒有找到線索的源代碼,這個快速瀏覽後...
我的理解是,它會在像側通從西斯塔VM回調發生,但是這是正在進行的工作,只有我模糊的回憶。 Clement Bera正在寫關於這個的博客(http://clementbera.wordpress.com上的sista編年史)

如果你害怕挖掘VMMaker源代碼,我邀請你去問問vm-dev.lists.squeakfoundation.org我很漂亮肯定艾略特米蘭達或克萊門特很樂意給你一個更準確的答案。

編輯

我忘了告訴你關於上述perigrinations的結論:我認爲會有一個非常小的差異,如果你直接使用研究所。變種。而不是一個getter,但這不應該是真正引人注目的,並且在任何情況下,您的編程風格都不應該被這種可忽略的優化所引導。

+0

我認爲編譯器不能真正優化= self someProperty =,因爲子類可能會覆蓋此方法和編譯器在編譯時無法知道所有的子類。還有「快速」方法的概念。將#isQuick發送到CompiledMethod並查看此消息的發件人。 – 2014-10-31 10:51:27

+0

@DamienCassou是的,快速方法是標記爲發送快速原語,儘管源代碼中沒有,我所有的答案都是關於虛擬機中處理它們的機制......案例的覆蓋是由PIC在VM中處理的,這就是內聯如此牽扯的原因。因此,使用更高級別的語言處理圖像內聯,但僅限於虛擬機檢測到的熱點,這不是一個不錯的選擇。 – 2014-10-31 14:39:40