我正在創建一個渲染引擎。我創建任務管理系統的方法有兩種。創建自己的自定義回調函數,在渲染之前和之後調用,或者實現一個任務管理系統,我必須從父類TaskClass派生一個類,然後將其放入隊列中。回撥費用是多少?
老實說,我覺得創建回調更好,因爲它允許我創建獨立於實際渲染引擎的任務管理子系統。這使我可以更多地關注渲染引擎並在以後擔心任務管理。
但是我的問題是......「使用回調代價高昂嗎?」 這是一種在遊戲引擎等處理器密集環境中常見的做法。
我正在創建一個渲染引擎。我創建任務管理系統的方法有兩種。創建自己的自定義回調函數,在渲染之前和之後調用,或者實現一個任務管理系統,我必須從父類TaskClass派生一個類,然後將其放入隊列中。回撥費用是多少?
老實說,我覺得創建回調更好,因爲它允許我創建獨立於實際渲染引擎的任務管理子系統。這使我可以更多地關注渲染引擎並在以後擔心任務管理。
但是我的問題是......「使用回調代價高昂嗎?」 這是一種在遊戲引擎等處理器密集環境中常見的做法。
首先,昂貴是相對的,如果你將這些回調稱爲10000Hz,是的,一些回調實現可能代價太高。但是,一個簡單的基於函數指針的回調實際上幾乎沒有開銷。
但最重要的是:這是一個過早優化的例子,當然它看起來你打算在每秒平均30幀的比賽中每秒只能調用這些回調60次。在大多數遊戲中,會有更多關鍵的性能問題。從一種方法開始,在出現性能問題時對其進行分析,如果確實不夠,則優化它。無論如何,你可能會在數學或AI功能上放鬆更多的CPU週期。最後:在許多遊戲中,瓶頸是GPU,而不是CPU;)。
那麼,回調將只用於CPU任務,如AI和遊戲機制,我並不太擔心。 – numerical25 2010-06-21 09:18:56
回調是一個函數指針。通過一個函數調用函數不是很昂貴,但肯定會導致一些開銷 - 函數至少不會被內聯。
只有你可以證明你是否可以負擔得起它 - 寫一個小測試程序並描述它。根據您將調用該函數的頻率,開銷將佔用更少或更多的處理器時間。沒有分析預測和分析是不值得的。
是的,我只是試圖看看有沒有人在渲染引擎或遊戲引擎中分析回調的經驗。如果不是完整的cpu週期,我會假定回調將被稱爲1/30或1/60秒。誰知道。 – numerical25 2010-06-21 09:24:46
嗯...什麼?你正在設計哪種處理器,需要整個1/30秒才能通過函數指針調用函數? – sharptooth 2010-06-21 09:59:59
我在搞directX api。如果我是動畫。我希望我的物體每秒移動30幀,換句話說,每秒移動30秒。因此,我處理更新節目的回調將被稱爲1/30秒。與以常規CPU速度移動相比,這相當慢。所以我認爲它不會那麼糟糕 – numerical25 2010-06-22 15:50:16
回調是非常便宜,當他們不涉及關閉。
涉及閉包的回調有點貴。
回調本身並不昂貴,但應注意不要做太多的計算。通常回調發布消息,給出信號/信號等並停止。
「使用回調代價高昂嗎?」
它可以像調用虛函數一樣小。
根據您的環境,它可能會更加昂貴:例如,如果它是從內核模式到用戶模式的回調,那麼您可能需要做巧妙的和/或昂貴的事情來實現明顯的振鈴轉換。
回調的問題之一是鎖定:如果您的代碼是多線程和/或線程安全的,那麼如果您在調用回調時擁有任何鎖定(取決於回調中的用戶代碼如,試圖獲得更多的鎖),你可能會陷入僵局。
在下使用函數指針進行時,對於這個小片斷
void func1() { }
void func2()
{
void (*funcptr)() = func1;
func1();
funcptr();
}
GCC -S生成用於FUNC2的主體下面的彙編指令關於回調的成本:
movq $func1, -8(%rbp)
movl $0, %eax
call func1
movq -8(%rbp), %rdx
movl $0, %eax
call *%rdx
所以如預期的那樣,您只需支付指針間接性,即您不必擔心性能。
如果您正在使用Visual Studio並查看任務管理系統,請查看VS 2010中的併發運行時,並行模式庫和代理庫here。
你不需要建立你自己的任務系統,你可以建立一個任務系統。
既然你有一個C++編譯器,是不是有你沒有用C++編寫的原因?我問的原因是虛擬功能比回調更好。 – 2010-06-22 00:03:04