Блок памяти, выделенный потоком, находится в той же близости, что и сам поток, до выхода из потока?

Это вопрос о NUMA.

Например, в приведенном ниже коде выделяется ли буфер в локальной памяти потока/процесса на протяжении всей его жизни?

    for (int th = 0; th < maxThreads; th++)
    {
        threads[th] = std::thread([&, th] {
            int* buffer = new int[1000];

            // do something 

            delete []buffer;
        }
    }

Обновление: чтобы сделать вопрос более простым, позвольте мне задать его таким образом. Если у меня запущено 10 одновременных потоков (скажем, от t0 до t9), и в рамках каждого потока он выделяет блок памяти (скажем, от m0 до m9). Будет ли поток t_n всегда работать с m_n (n от 0 до 9) перед выходом из потока, или поток 0 может мигрировать и работать с памятью 9? Блок памяти в моей ситуации не очень большой, обычно всего пару мегабайт.


person photoelectric    schedule 02.07.2018    source источник
comment
Это будет зависеть от реализации; какой у тебя компилятор?   -  person kmdreko    schedule 02.07.2018
comment
связанные: stackoverflow.com/questions/2142107/   -  person kmdreko    schedule 02.07.2018
comment
В основном я использую компилятор Visual Studio или компилятор Intel (в комплекте с Visual Studio).   -  person photoelectric    schedule 02.07.2018
comment
Учитывая, что вы используете Visual Studio, вы, вероятно, захотите начать отсюда: docs.microsoft.com/en-us/windows/desktop/procthread/   -  person Andrew Henle    schedule 02.07.2018
comment
спасибо @AndrewHenle Я не уверен, как понять это предложение о VirtualAllocExNuma в конце первого раздела: если в предпочтительном узле заканчиваются страницы, диспетчер памяти будет использовать страницы из других узлов. Если память выгружается, тот же процесс используется при ее возвращении. Означает ли это, что если память выделяется из другого узла, процесс использует память также на этом другом узле?   -  person photoelectric    schedule 03.07.2018


Ответы (2)


Я думаю, что такое поведение связано с реализацией ОС, но я считаю, что для Linux, настроенного и собранного с опцией CONFIG_NUMA, ответ будет ДА.

NUMA в Linux

person Binghe Zhai    schedule 02.07.2018

Если вы не вызываете какую-либо функцию, чтобы сообщить ей об обратном, большинство реализаций будут «чередовать» всю память, уменьшая стоимость памяти неправильного узла.

Для любого заданного небольшого распределения это означает, что узел в основном является случайным.

См. "что должен знать каждый программист о памяти, часть 4"

person o11c    schedule 02.07.2018
comment
Значит, вы говорите, что небольшой блок памяти распределяется между узлами случайным образом, даже если он выделяется внутри потока? Кажется, это противоречит тому, что я узнал раньше. Например, это говорит о том, что современные ОС (по крайней мере, Linux, другие, вероятно, тоже) до сих пор хорошо справляются с задачей, память по умолчанию выделяется (если доступна) из того же домена ЦП, где работает поток stackoverflow.com/questions/24645880/ - person photoelectric; 02.07.2018
comment
Там определенно противоречивая информация ... Я признаю, что мой источник более старый. Но при отсутствии настройки сходства чередующаяся память является оптимальным решением, и я убедился, что процессы делают частую миграцию. И закрепление сложно, когда вам нужно беспокоиться о других процессах в системе. - person o11c; 02.07.2018
comment
Я согласен с тем, что процессы действительно часто мигрируют, так как это именно то, на что нацелена set affinity. Вопрос, который я здесь задаю, немного другой. Я спрашиваю в многопоточности внутри потока, будет ли поток/процесс также мигрировать, даже если блок памяти выделен внутри этого потока. То есть, если у меня есть 10 одновременных потоков (скажем, от t0 до t9), в рамках каждого потока он выделяет блок памяти (скажем, от m0 до m9). Будет ли поток t_n всегда работать с m_n (n от 0 до 9) перед выходом из потока, или, как вы сказали, поток 0 может мигрировать и работать с памятью 9? - person photoelectric; 02.07.2018