1

我有一台带有 AMD Threadripper 3990x 的新 PC,它有 64 个内核和 128 个线程。

现在 Windows 10 只能在一个处理器组中处理 64 个内核。所以现在 Windows 制造了两个处理器组。

我编写了创建 N 个进程的软件。我检查如下有多少进程存在:

SYSTEM_INFO sysi;
GetSystemInfo(&sysi);
klas->thread_maxcore = min(sysi.dwNumberOfProcessors, MAX_THREADS);
klas->thread_max = klas->thread_maxcore;

如何调整我的代码以使用所有 128 个线程?使用我当前的代码,我一次只能运行 64 个进程,因此只能使用一个处理器组。

4

2 回答 2

2

我如何调整我的代码以使用所有 128 个线程

简短的回答是让您的软件处理器组知道,或者强制您的配置只有一个处理器组。

正如您所指出的,Windows 默认情况下,当看到超过 64 个线程时,会将它们分成处理器组。这可能就是您看到的线程数似乎较少的原因。虽然线程数少于您的预期,但它可能仅代表系统总线程数的一部分。

有一个同时多线程设置,默认情况下,在 Windows 10 中,此设置已打开。对于您的 64 核处理器,当同时启用多线程时,系统将显示 128 个线程,但这些线程分为两组。这种默认的 Windows 行为可能是阻止您查看(可见)所有线程的原因。关于您的具体要求我如何调整我的代码以使用所有 128 个线程

...当程序在组内运行时,除非它是处理器组感知的,否则它只能访问同一组中的其他线程...

因此,答案是让您了解软件处理器组,或者通过禁用同时多线程进行设置以将所有内核放入单个处理器组,从而允许您的软件生成所有 128 个线程。
以下链接中更详细地介绍了这两种选择的方法和权衡...

在此处阅读详细信息...
64 核 Threadripper 3990x CPU 评测

一些可能有助于使您的软件处理器组了解的链接:

摘自上一个链接的改编 C++代码(由于此问题已标记C,因此将其视为伪代码

void DistributeThreads(void)
{
#if OS_WINDOWS_64
    //!!BUG!! need to skip this code for old windows versions
        int nNumGroups = GetActiveProcessorGroupCount();
    if ( nNumGroups > 1 )
    {
        Log( "System has %d processor groups", nNumGroups );
        for(int i = 0; i < nNumGroups; i++ )
        {
            Log(" group %d has %d processors", i, ( int ) GetMaximumProcessorCount( i ) );
        }
        int nCurGroup = 0;
        int nNumRemaining = GetMaximumProcessorCount( nCurGroup );
        for( int i = 0; i < m_threads.size(); i ++ )
        {
            auto hndl = m_threads[i].native_handle();
            GROUP_AFFINITY oldaffinity;
            if ( GetThreadGroupAffinity( hndl, &oldaffinity ) )
            {
                //Log( "thread %d, old msk = %x, old grp = %llx", i, oldaffinity.Mask, oldaffinity.Group );
                GROUP_AFFINITY affinity;
                affinity = oldaffinity;
                if ( affinity.Group != nCurGroup )
                {
                    affinity.Group = nCurGroup;
                    auto bSucc = SetThreadGroupAffinity( hndl, &affinity, nullptr );
                    if ( ! bSucc )
                    {
                        Log( "failed to set gr aff err=%x", (int) GetLastError() );
                    }
                    else
                    {
                        //Log( "Set group for thread %d to %d", i, nCurGroup );
                    }
                    --nNumRemaining;
                    if ( nNumRemaining == 0 )
                    {
                        nCurGroup = min( nCurGroup + 1 , nNumGroups - 1 );
                        nNumRemaining = GetMaximumProcessorCount( nCurGroup );
                    }
                }
            }
        }
    }
#endif
}  

注意:在 MSDN 中搜索函数定义,例如:GetMaximumProcessorCount

于 2020-04-28T12:45:42.713 回答
0

该链接指向我的代码和文章。我刚买了一个 128 核/256 线程和系统,正如你所料,Windows 处理器组意味着大多数程序只使用我的 1/4 内核。包括可视化 c++ 并行 STL 算法 :(。该代码有效,但省去了所有麻烦,只需使用 Intel TBB。当您下载适用于 Windows 的线程应用程序并注意到它仅使用您系统的 25% 时,它真的很糟糕。不要我不指望 msoft 对此做任何事情。我联系了 Visual C++ 团队,他们都关心我们为这个问题找借口。

于 2021-10-05T00:59:27.460 回答