summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDave Parks <davep@lindenlab.com>2022-11-30 13:25:00 -0600
committerDave Parks <davep@lindenlab.com>2022-11-30 13:25:00 -0600
commit87bb72a47a1fc64b98e498120e332de76e6a9211 (patch)
tree1e48ca7915525368bf3eda06447ab4edcaf0be60
parentadbd264d35f5fabe28249839da6c12e5dac4127f (diff)
SL-18154 WIP -- CPU sampling (AMD uProf) profile guided optimizations to reduce CPU usage of background threads.
-rw-r--r--indra/llcommon/llqueuedthread.cpp9
-rw-r--r--indra/llcommon/llthread.cpp10
-rw-r--r--indra/llcommon/lltimer.cpp4
-rw-r--r--indra/llwindow/llwindowwin32.cpp18
-rw-r--r--indra/newview/llappviewer.cpp6
5 files changed, 44 insertions, 3 deletions
diff --git a/indra/llcommon/llqueuedthread.cpp b/indra/llcommon/llqueuedthread.cpp
index e5060a1076..9b1de2e9a5 100644
--- a/indra/llcommon/llqueuedthread.cpp
+++ b/indra/llcommon/llqueuedthread.cpp
@@ -477,9 +477,14 @@ void LLQueuedThread::processRequest(LLQueuedThread::QueuedRequest* req)
mRequestQueue.post([=]
{
LL_PROFILE_ZONE_NAMED("processRequest - retry");
- while (LL::WorkQueue::TimePoint::clock::now() < retry_time)
+ if (LL::WorkQueue::TimePoint::clock::now() < retry_time)
{
- std::this_thread::yield(); //note: don't use LLThread::yield here to avoid
+ auto sleep_time = std::chrono::duration_cast<std::chrono::milliseconds>(retry_time - LL::WorkQueue::TimePoint::clock::now());
+
+ if (sleep_time.count() > 0)
+ {
+ ms_sleep(sleep_time.count());
+ }
}
processRequest(req);
});
diff --git a/indra/llcommon/llthread.cpp b/indra/llcommon/llthread.cpp
index a807acc56e..4eaa05c335 100644
--- a/indra/llcommon/llthread.cpp
+++ b/indra/llcommon/llthread.cpp
@@ -42,6 +42,7 @@
#ifdef LL_WINDOWS
+
const DWORD MS_VC_EXCEPTION=0x406D1388;
#pragma pack(push,8)
@@ -133,6 +134,15 @@ void LLThread::threadRun()
{
#ifdef LL_WINDOWS
set_thread_name(-1, mName.c_str());
+
+#if 0 // probably a bad idea, see usage of SetThreadIdealProcessor in LLWindowWin32)
+ HANDLE hThread = GetCurrentThread();
+ if (hThread)
+ {
+ SetThreadAffinityMask(hThread, (DWORD_PTR) 0xFFFFFFFFFFFFFFFE);
+ }
+#endif
+
#endif
LL_PROFILER_SET_THREAD_NAME( mName.c_str() );
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 8739eeef00..24eaa4c1a9 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -92,6 +92,7 @@ U32 micro_sleep(U64 us, U32 max_yields)
U32 micro_sleep(U64 us, U32 max_yields)
{
LL_PROFILE_ZONE_SCOPED
+#if 0
LARGE_INTEGER ft;
ft.QuadPart = -static_cast<S64>(us * 10); // '-' using relative time
@@ -99,6 +100,9 @@ U32 micro_sleep(U64 us, U32 max_yields)
SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
WaitForSingleObject(timer, INFINITE);
CloseHandle(timer);
+#else
+ Sleep(us / 1000);
+#endif
return 0;
}
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index c0d3424141..be5af8240f 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -467,7 +467,6 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
// process deprioritization during profiles
// force high thread priority
HANDLE hProcess = GetCurrentProcess();
- HANDLE hThread = GetCurrentThread();
if (hProcess)
{
@@ -484,6 +483,20 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
}
}
}
+#endif
+
+#if 0 // this is also probably a bad idea, but keep it in your back pocket for getting main thread off of background thread cores (see also LLThread::threadRun)
+ HANDLE hThread = GetCurrentThread();
+
+ SYSTEM_INFO sysInfo;
+
+ GetSystemInfo(&sysInfo);
+ U32 core_count = sysInfo.dwNumberOfProcessors;
+
+ if (max_cores != 0)
+ {
+ core_count = llmin(core_count, max_cores);
+ }
if (hThread)
{
@@ -499,6 +512,9 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
{
LL_INFOS() << "Failed to set thread priority: " << std::hex << GetLastError() << LL_ENDL;
}
+
+ // tell main thread to prefer core 0
+ SetThreadIdealProcessor(hThread, 0);
}
}
#endif
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 6e0bbb05ee..dcc12a865b 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -2181,6 +2181,12 @@ bool LLAppViewer::initThreads()
// get the number of concurrent threads that can run
S32 cores = std::thread::hardware_concurrency();
+ U32 max_cores = gSavedSettings.getU32("EmulateCoreCount");
+ if (max_cores != 0)
+ {
+ cores = llmin(cores, (S32) max_cores);
+ }
+
// The only configurable thread count right now is ImageDecode
// The viewer typically starts around 8 threads not including image decode,
// so try to leave at least one core free