2013-07-25 32 views
0

我們有一個在Solaris(5.10,sparc平臺)上運行的多線程C++應用程序。根據「pstack」,大部分線程似乎都在等待下面的調用,時間太長。這對應於應用程序代碼中的「time_t currentTime = time(NULL) ;」函數以秒爲單位獲取當前時間。C++在solaris中的time()函數性能

ffffffff76cdbe1c __time (0, 23e8, 1dab58, ffffffff76c63508, ffffffff76e3e000, 2000) + 8 

的時區是 「亞洲/利雅得」。我嘗試將TZ變量設置爲「亞洲/利雅得」以及「<GMT+3>-3」。但兩種方案都沒有明顯的改善。在這一點上更改服務器代碼(即使有替代選擇)也很困難。一個測試程序(單線程,編譯時沒有-O2)有100萬個「time(NULL)」的調用很快就出來了。應用程序&測試程序使用gcc 4.5.1進行編譯。

還有什麼我可以嘗試嗎?

我同意這是一個相當廣泛的問題。我會嘗試一下有效的建議,並在有足夠的改進來處理當前的負載時立即關閉它。

編輯1:

請忽略的參考以上時間(NULL),作爲一個可能的原因__time堆棧。我根據簽名進行推理,並在源方法中找到相同的調用。

以下是導致__time的另一個堆棧。

ffffffff76cdbe1c __time (0, 23e8, 1dab58, ffffffff773e5cc0, ffffffff76e3e000, 2000) + 8 
ffffffff76c9c7f0 getnow (ffffffff704fb180, ffffffff773c6384, 1a311c, 2, ffffffff76e4eae8, fffc00) + 4 
ffffffff76c9af0c strptime_recurse (ffffffff76e4cea0, 1, 104980178, ffffffff704fb938, ffffffff704fb180, ffffffff704fb1a4) + 34 
ffffffff76c9dce8 __strptime_std (ffffffff76e4cea0, 10458b2d8, 104980178, ffffffff704fb938, 2400, 1a38ec) + 2c 
+1

時區對'time()'的返回值沒有影響,至少在Unix下。它始終是UTC。 –

+1

你應該提供更多的證據,「時間」真的是罪魁禍首。 'truss -c command'或dtrace'procsystime -aTn yourApp'輸出會有所幫助。順便說一下,設置TZ對於自定義時間無任何影響。 (編輯:對於後面的評論來說太遲了......) – jlliagre

+1

@JoachimPileborg編譯器會優化調用'time'的命令,這讓我感到驚訝。它是一個外部函數,它的行爲是編譯器無法看到的,因此編譯器必須假定它可能具有可觀察的行爲。 –

回答

1

您(和我們)無法加快time的速度。 從你的消息中,我收集到你一次從很多不同的線程調用它。這可能是一個問題;這很可能是Solaris連續執行這些調用的原因,因此您最終會在 之前等待其他人完成。

你需要多少準確度?一個可能的解決方案可能是 在讀取時間時有一個線程循環,在每次讀取之間可能睡眠10毫秒,並將結果放入其他線程讀取的全局變量 中。 (不要忘了,你需要 同步所有訪問該變量,除非你有一些 某種原子變量,就像在C++ 11 std::atomic<time_t>

+0

是的,它是從多個線程中調用的。準確性非常重要。此外,我現在無法不幸地改變服務器代碼。 – mpathi

1

請記住,沒有按pstack只是立即中斷你的程序並生成一個堆棧。它必須獲得調試級別的控制權,並且如果調用足夠頻繁,它可能會大大超出對time的調用,因爲它利用這些系統調用來控制應用程序以打印堆棧。

最有可能的time調用不是真正的性能問題的來源。我懷疑你會想要利用一個分析器,如gprof(與g++ -p)。或者,您可以使用一些dtrace套件並使用hotuser dtrace腳本,該腳本將對正在運行的應用程序的用戶代碼進行基本的統計分析。

time返回UTC時間,因此任何對TZ的更改都不應影響其通話時間。

如果在分析後發現time確實是罪魁禍首,您可能會緩存來自time調用的值,因爲它不會每秒更改一次。

+0

pstack觀察是基於過去幾天的快照。在代碼的不同部分有與時間相關的調用。 pstack幾乎總是顯示__time,儘管來自我們代碼中的不同方法。代碼中有大量的其他操作,這些操作並不經常出現在pstack中。性能分析需要重新編譯(在生產機器中觀察到此問題)。關於TZ,如上所述,我可能在time()調用時出錯。還有一個localtime()調用。但我不確定這一點。 – mpathi