2016-03-02 59 views
6

好像localtime_s()(與標準localtime_r相同)在MSVC中包含關鍵部分。在Windows上使用localtime_s()的多線程性能不佳的解決方法

爲了進行比較,下面是2個示例應用程序,其中一個是localtime_s,其他gmtime_s

剖析顯示內部isindst重鎖爭從common_localtime_s<__int64>稱爲:

localtime lock contention

gmtime不會出現問題:

gmtime no lock contention

有什麼辦法來解決此線程環境中得到理智localtime_s性能,提供確實需要本地時間在我的過程嗎?

+0

實際上你是否經常調用這個函數,以至於它是一個瓶頸? –

+0

是的,它目前佔用了所有運行時間(64個CPU)的70%。 – rustyx

+0

是的,我看到了同樣的問題。多線程環境下localtime_s速度較慢。我無法找到解決方案。 – SergeyA

回答

2

這裏是一個建議的解決方案:

記錄所有倍,無論是最快的。當通過GUI,日誌文件或其他方式將它們呈現給用戶時,請轉換爲當地時間。

由於大多數圖形用戶界面和日誌輸出都是單線程的,因此應該從程序的其餘部分中刪除爭用。

如果程序從不將數據呈現給用戶,那麼只需以快速時間格式將其寫出,並使用後處理工具將其轉換或顯示出來。

+0

的確我最終在內部使用'gmtime'。但是我通過複製MS CRT實現並使所有的'static'變量'thread_local'(並去掉當然的鎖)實現'localtime_lockfree'。不幸的是,我不能共享生成的代碼,因爲MSCRT許可證禁止共享修改後的源代碼:( – rustyx

2

由於標準實現使用鎖,並且沒有簡單的方法,所以您可能必須使用不同的實現。我建議嘗試以GetTimeZoneInformationForYear爲基礎,它將爲您提供UTC的標準時間和夏令時時間的偏移量以及DST處於活動狀態的日期。您也可以選擇每年關注一次並緩存結果供所有線程使用。

既然gmtime_s表現可以接受,我會建議您使用此獲得年份。 (請注意,這是localtime_s的作用。)減去GetTimeZoneInformationForYear提供的相應偏差值,然後再使用gmtime_s將其拆分爲日期分量。

+0

非常有趣,似乎MS CRT中的實現不使用此API,但始終使用當前時區('GetTimeZoneInformation')這種方式實際上可以更準確。順便說一句,CRT實現也支持'TZ'環境變量作爲覆蓋。 – rustyx

相關問題