I am currently investigating Redis, and for tuning its capabilities, we need to change settings for ThreadPool, specifically minimum numbers of Worker/IOC threads.
We're hosting application in Azure Web Role, as well as a part of it in a Worker Role.
Reading documentation for asp.net, I found processModel.miniothreads
element of web.config, which says:
Configures the minimum number of I/O threads to use for the process on a per-CPU basis. Also see maxIoThreads.
So technically, I read this as number of threads per Processor Core, correct me if I'm wrong.
Unfortunately, we cannot use this setting for a Worker Role, since it's not hosted using ASP.NET, so documentation from Microsoft says to use ThreadPool.SetMinThreads
.
I tried researching, if this setting is per-CPU or not(within a process), but I found nothing - all paths lead me to checking source at mscoree.lib
, which I'm not even sure is possible currently, at least without digging in for a couple of days.
Decompiled code is:
[System.Security.SecuritySafeCritical] // auto-generated
[SecurityPermissionAttribute(SecurityAction.Demand, ControlThread = true)]
public static bool SetMinThreads(int workerThreads, int completionPortThreads)
{
return SetMinThreadsNative(workerThreads, completionPortThreads);
}
[System.Security.SecurityCritical] // auto-generated
[ResourceExposure(ResourceScope.None)]
[MethodImplAttribute(MethodImplOptions.InternalCall)]
private static extern bool SetMinThreadsNative(int workerThreads, int completionPortThreads);
So my question is, are ThreadPool.SetMinThreads
and ThreadPool.SetMaxThreads
per core?
Also is there any major difference between using processModel.miniothreads
setting in web.config and ThreadPool
settings in application start apart?
[Update]: I found source code for implementation in mono: https://github.com/mono/mono/blob/7ebae4c7f57a6c1b4d0a38e69f270a016b6f3143/mono/metadata/threadpool-ms.c
MonoBoolean
ves_icall_System_Threading_ThreadPool_SetMinThreadsNative (gint32 worker_threads, gint32 completion_port_threads)
{
mono_lazy_initialize (&status, initialize);
if (worker_threads <= 0 || worker_threads > threadpool->limit_worker_max)
return FALSE;
if (completion_port_threads <= 0 || completion_port_threads > threadpool->limit_io_max)
return FALSE;
threadpool->limit_worker_min = worker_threads;
threadpool->limit_io_min = completion_port_threads;
return TRUE;
}
Only places limits and number of cores used are validation:
MonoBoolean
ves_icall_System_Threading_ThreadPool_SetMaxThreadsNative (gint32 worker_threads, gint32 completion_port_threads)
{
gint cpu_count = mono_cpu_count ();
mono_lazy_initialize (&status, initialize);
if (worker_threads < threadpool->limit_worker_min || worker_threads < cpu_count)
return FALSE;
if (completion_port_threads < threadpool->limit_io_min || completion_port_threads < cpu_count)
return FALSE;
threadpool->limit_worker_max = worker_threads;
threadpool->limit_io_max = completion_port_threads;
return TRUE;
}
and setting defaults:
threads_count = mono_cpu_count () * threads_per_cpu;
threadpool->limit_worker_min = threadpool->limit_io_min = threads_count;
So for mono looks like thread pool takes number of cores into account only for validating max number of threads: max number of threads cannot be less than number of cores.
Is the same applicable to .NET implementation? Is there any way I can find sources for that?