C обработка потоков двумя группами процессоров - PullRequest
1 голос
/ 28 апреля 2020

каждый,

У меня есть новый P C с AMD Threadripper 3990x, который имеет 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 процесса на время, поэтому можно использовать только одну группу процессоров.

Заранее большое спасибо

1 Ответ

2 голосов
/ 28 апреля 2020

Как мне настроить свой код так, чтобы он использовал все 128 потоков

Краткий ответ - либо заставить ваше программное обеспечение знать группу процессоров , либо заставить ваш В конфигурации должна быть только одна группа процессоров.

Как вы заметили, Windows по умолчанию при просмотре более 64 потоков это разделение их на группы процессоров. Возможно, именно поэтому вы видите то, что кажется меньшим числом потоков. Хотя число потоков меньше ожидаемого, возможно, оно представляет только часть общего числа системных потоков.

Существует настройка для одновременной многопоточности , и она по умолчанию в Windows 10 включена. На 64-ядерном процессоре при включенной одновременной многопоточности 1014 * система покажет 128 потоков, но они разделены на две группы. Это поведение по умолчанию Windows может быть тем, что мешает вам видеть (иметь видимость) все ваши потоки. Относительно вашего указанного c запроса Как мне настроить свой код для использования всех 128 потоков ,

... Когда программа работает внутри группы, если только она если группа процессоров осведомлена, то она может получить доступ только к другим потокам в той же группе ...

Итак, ответ заключается в том, чтобы либо уведомить вас о группе процессоров программного обеспечения, либо настроить параметры размещения всех ядер. в одну группу процессоров путем отключения одновременной многопоточности , что позволяет вашему программному обеспечению порождать все 128 потоков.
Методы и компромиссы для обоих вариантов более подробно представлены в ссылках ниже. ..

Подробнее читайте здесь ...
Обзор 64-ядерного процессора Threadripper 3990x .

Некоторые ссылки, которые могут помочь в информировании вашей группы программных процессоров:

Выдержка адаптированный 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

...