2010-06-21 73 views
3

我正在創建一個渲染引擎。我創建任務管理系統的方法有兩種。創建自己的自定義回調函數,在渲染之前和之後調用,或者實現一個任務管理系統,我必須從父類TaskClass派生一個類,然後將其放入隊列中。回撥費用是多少?

老實說,我覺得創建回調更好,因爲它允許我創建獨立於實際渲染引擎的任務管理子系統。這使我可以更多地關注渲染引擎並在以後擔心任務管理。

但是我的問題是......「使用回調代價高昂嗎?」 這是一種在遊戲引擎等處理器密集環境中常見的做法。

+0

既然你有一個C++編譯器,是不是有你沒有用C++編寫的原因?我問的原因是虛擬功能比回調更好。 – 2010-06-22 00:03:04

回答

5

首先,昂貴是相對的,如果你將這些回調稱爲10000Hz,是的,一些回調實現可能代價太高。但是,一個簡單的基於函數指針的回調實際上幾乎沒有開銷。

但最重要的是:這是一個過早優化的例子,當然它看起來你打算在每秒平均30幀的比賽中每秒只能調用這些回調60次。在大多數遊戲中,會有更多關鍵的性能問題。從一種方法開始,在出現性能問題時對其進行分析,如果確實不夠,則優化它。無論如何,你可能會在數學或AI功能上放鬆更多的CPU週期。最後:在許多遊戲中,瓶頸是GPU,而不是CPU;)。

+0

那麼,回調將只用於CPU任務,如AI和遊戲機制,我並不太擔心。 – numerical25 2010-06-21 09:18:56

2

回調是一個函數指針。通過一個函數調用函數不是很昂貴,但肯定會導致一些開銷 - 函數至少不會被內聯。

只有你可以證明你是否可以負擔得起它 - 寫一個小測試程序並描述它。根據您將調用該函數的頻率,開銷將佔用更少或更多的處理器時間。沒有分析預測和分析是不值得的。

+0

是的,我只是試圖看看有沒有人在渲染引擎或遊戲引擎中分析回調的經驗。如果不是完整的cpu週期,我會假定回調將被稱爲1/30或1/60秒。誰知道。 – numerical25 2010-06-21 09:24:46

+0

嗯...什麼?你正在設計哪種處理器,需要整個1/30秒才能通過函數指針調用函數? – sharptooth 2010-06-21 09:59:59

+0

我在搞directX api。如果我是動畫。我希望我的物體每秒移動30幀,換句話說,每秒移動30秒。因此,我處理更新節目的回調將被稱爲1/30秒。與以常規CPU速度移動相比,這相當慢。所以我認爲它不會那麼糟糕 – numerical25 2010-06-22 15:50:16

0

回調是非常便宜,當他們不涉及關閉。

涉及閉包的回調有點貴。

0

回調本身並不昂貴,但應注意不要做太多的計算。通常回調發布消息,給出信號/信號等並停止。

0

「使用回調代價高昂嗎?」

它可以像調用虛函數一樣小。

根據您的環境,它可能會更加昂貴:例如,如果它是從內核模式到用戶模式的回調,那麼您可能需要做巧妙的和/或昂貴的事情來實現明顯的振鈴轉換。

回調的問題之一是鎖定:如果您的代碼是多線程和/或線程安全的,那麼如果您在調用回調時擁有任何鎖定(取決於回調中的用戶代碼如,試圖獲得更多的鎖),你可能會陷入僵局。

5

在下使用函數指針進行時,對於這個小片斷

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 

所以如預期的那樣,您只需支付指針間接性,即您不必擔心性能。

0

如果您正在使用Visual Studio並查看任務管理系統,請查看VS 2010中的併發運行時,並行模式庫和代理庫here

你不需要建立你自己的任務系統,你可以建立一個任務系統。