Согласованность кэша: потоки против ядер - PullRequest
2 голосов
/ 22 мая 2019

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

Некоторые предположения, которые я понимаю:

  • Ядра имеют кеши
  • Ядра могут иметь несколько потоков одновременно (если гиперзарезная)
  • Поток - это отдельная строка команд, которые обрабатываются
  • Таким образом, потоки не являются физическим оборудованием, а потоки не имеют кешей и используют кеш ядра

Предположим, ядро ​​имеет у нас есть два потока, а x - этообщая переменная со значением пять.Оба хотят выполнить:

my_y = x;

Где my_y - закрытая переменная, определяемая обоими потоками.Теперь предположим, что поток 0 выполняется:

x++;

Наконец, предположим, что поток 1 теперь выполняется:

my_z = x;

Где my_zдругая личная переменная.

Моя книга говорит следующее:

Какое значение в my_z?Это пять?Или это шесть?Проблема в том, что существует (как минимум) три копии x: одна в основной памяти, одна в кэше потока 0 и одна в кэше потока 1.

Как это сделатьРабота?Как существует по крайней мере три копии x и почему в книге указано, что каждый поток имеет свой собственный кэш?Для меня было бы разумно, чтобы ядро, на котором запущены два потока, имело значение x в своем кеше, и, таким образом, оба потока имеют значение в «своем» (общем) кэше.

В другомслова, когда x++ обновляется, значение в кеше ядра будет обновляться.Затем поток 1 будет выполнять my_z = x;, который все еще находится в кэше ядра, и он обновлен.Таким образом, не было бы проблемы когерентности, потому что два потока в основном совместно используют кеш.

Возможно, в книге предполагается, что каждое ядро ​​имеет только один поток, но в книге ранее упоминалось что-то о том, «если естьбольше потоков, чем ядер ".Означает ли «если потоков больше, чем ядер», подразумевается, что ядро ​​имеет более одного потока (гиперпоточность), или происходит какое-то планирование потоков, так что каждое ядро ​​имеет только один поток за раз?

Четныйесли это так (планирование ядер и то, что ядро ​​может иметь только один поток за раз), если ядру принадлежит поток 0, выполняется x++, а затем получается поток 1, который пытается выполнить my_z = x; значениеЕсли я не ошибаюсь, в кэше этого ядра все еще будет присутствовать x.

Дополнительный вопрос: как частные переменные потоков хранятся в памяти?Хранятся ли они так же, как любая переменная, куда они копируются в кеш ядра при использовании?Если это так, то будет ли проблемой иметь личную переменную в кеше ядра, если кеш использует несколько потоков - одновременно или по расписанию?

Согласно запросу @biziclop, книга утверждаетследующие предположения:

  • Мы используем системы MIMD, то есть узлы имеют одинаковую архитектуру.(Однако в книге не указано, какая именно это архитектура)
  • Наши программы SPMD.Таким образом, мы напишем одну программу, которая может использовать ветвление для нескольких вариантов поведения.
  • Мы предполагаем, что ядра идентичны, но работают асинхронно.
  • Мы программируем на языке C, и в этом разделе мысосредоточены на Pthreads.

Буду признателен за любую помощь!

1 Ответ

3 голосов
/ 22 мая 2019

почему в книге указано, что каждый поток имеет свой собственный кэш?

Автор неаккуратен.Темы не имеют кешей.Ядра процессора, на которых выполняются потоки, имеют кеши.

книга ранее делала [скажем, «если потоков больше, чем ядер».Означает ли [это], что ядро ​​имеет более одного потока (гиперпоточность) или происходит какое-то планирование потоков, так что каждое ядро ​​имеет только один поток за раз?

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

как частные переменные потоков хранятся в памяти?

Все потоки процесса видят одно и то же виртуальное адресное пространство.В самом широком смысле «private» просто описывает область памяти, которая используется только одним потоком, и не имеет значения , почему местоположение используется только одним потоком.

Inв более узком смысле, каждый поток имеет стек записей активации функций (иначе называемый «стек вызовов»), содержащий аргументы и локальные переменные всех вызовов активных функций.Во многих языках программирования один поток не может поделиться своими аргументами или локальными данными с любым другим потоком, поэтому эти области памяти автоматически становятся «частными».В других языках программирования возможно совместно использовать arg или local, но программист должен написать явный код, чтобы поделиться им, и в любом случае, это, вероятно, плохая идея.

Будет ли проблемой иметь личную переменную в кеше ядра, если кеш использует несколько потоков - одновременно или по расписанию?

Когда две разные ячейки памяти оба хэшируют к одному и тому жерасположение кеша, которое называется столкновением .И да!столкновения случаются несколько раз.Если определенная строка кэша содержит переменную X, а поток T хочет получить доступ к переменной Y, которая использует ту же самую строку кэша, то система памяти заставит поток T ждать, пока он извлекает данные из основной памяти.

Это явление также называется «ложное совместное использование» (как правило, когда оно становится проблемой), и вы можете воспользоваться Google для поиска стратегий, позволяющих избежать этого , если и когда вы определите, что это фактически снижает производительность вашей программы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...