2012-03-01 42 views
2

把這個功能讓時間的雙重使用clock_gettime:着色時間統一 - clock_gettime被截斷

// return current time in milliseconds 
static double time_get_ms(void) 
{ 
    struct timespec res; 

#ifdef ANDROID 
    clock_gettime(CLOCK_REALTIME_HR, &res); 
#else 
    clock_gettime(CLOCK_REALTIME, &res); 
#endif 
    return (double)(1000.0*res.tv_sec + res.tv_nsec/1e6); 
} 

其發送到着色器需要轉換爲浮動。尾數正在溢出,並在到着色器的路上被截斷。

實施例:

作爲雙= 1330579093642.441895

作爲浮子= 1330579111936.000000

的浮點值被卡住在用於長時間的單個數字,由於截斷。

它似乎甚至res.tv_sec秒的值是一個大的浮點數,它也被截斷到GPU的路上。

嘗試測量應用程序啓動以來的時間,並且我很快遇到了同樣的問題。

那麼,什麼是獲得運行時間值到着色器的最佳方式?在Linux世界中有一些跨平臺的東西(如IOS,Android,Linux)。

回答

4

您的尾數已經用完了32位浮點精度。着色器無法更好地處理這種精度不足的問題,因爲除非您使用雙精度支持的GL 4.x,否則着色器也只能處理32位浮點數。

如果你運行一個應用程序的時間超過浮點精度(這將需要約10毫秒或約2.7小時左右),那麼你必須找到一種方法來適當地處理這個問題情況。你究竟是怎麼做的,取決於你的着色器使用這個時間值。

大多數着色器不需要以毫秒爲單位的實際時間。絕大多數需要一定時間(或類似時間)的着色器過程是週期性的。在這種情況下,您可以簡單地向他們傳遞一個值,說明他們在特定的週期中有多遠。該值在[0,1)範圍內,在循環開始時爲0,中間爲0.5,結束時爲1。

如果你的着色器進程不能被參數化,如果它確實需要一個絕對時間,那麼你的下一個賭注是通過兩個浮點參數。基本上,你需要保持你的溢出位。這會使涉及GPU時間的所有數學複雜化,因爲您必須使用兩個值並知道如何將它們移植到一起才能進行時間​​更新。同樣,你如何做這取決於你在着色器中做什麼。

或者,如果您的硬件支持GL 3.x +,則可以使用32位無符號整數發送時間。這會給你更多的精度,所以它會延長問題的時間。如果你的時間只有十分之一毫秒,那麼你應該能夠在它溢出之前花費大約5天左右的時間。同樣,這會使所有的GPU數學複雜化,因爲你不能只進行一個int-to-float轉換。