ThreadPool.SetMinThreads and SetMaxThreads and num

2019-07-19 17:47发布

问题:

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?