В настоящее время я изучаю параллельные системы, и меня немного смутило понятие когерентности кэша при работе с несколькими потоками и несколькими ядрами одновременно.
Некоторые предположения, которые я понимаю:
- Ядра имеют кеши
- Ядра могут иметь несколько потоков одновременно (если гиперзарезная)
- Поток - это отдельная строка команд, которые обрабатываются
- Таким образом, потоки не являются физическим оборудованием, а потоки не имеют кешей и используют кеш ядра
Предположим, ядро имеет у нас есть два потока, а 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.
Буду признателен за любую помощь!