Многопоточность на многоядерной архитектуре - PullRequest
4 голосов
/ 28 июня 2010

Когда возникает ситуация, когда поток A читает некоторую глобальную переменную, а поток B записывает в одну и ту же переменную, теперь, если чтение / запись не являются атомарными для одного ядра, вы можете делать это без синхронизации, однако, что происходит при запуске на многоядерный компьютер?

Ответы [ 7 ]

9 голосов
/ 28 июня 2010

Даже на одном ядре нельзя предполагать, что операция будет атомарной.Это может быть в том случае, когда вы пишете код на ассемблере, но если вы пишете код на C ++ согласно вашему вопросу, вы не знаете , к чему он будет компилироваться.

Вам следуетполагаться на примитивы синхронизации на том уровне абстракции, на который вы кодируете.В вашем случае это потоки вызовов для C ++.будь то pthreads, потоки Windows или что-то еще целиком.

Это то же самое рассуждение, которое я привел в другом ответе относительно , был ли i ++ поточно-ориентированным .Суть в том, что вы не знаете, так как не кодируете до этого уровня (если вы делаете встроенный ассемблер и / или понимаете и можете контролировать то, что происходит под прикрытием, вы больше не кодируете наУровень C ++, и вы можете игнорировать мой совет).

Операционная система и / или библиотеки типа ОС знают о среде, в которой они работают, гораздо больше, чем компилятор C ++.Использование правильных синхронизирующих примитивов избавит вас от беспокойства.

7 голосов
/ 28 июня 2010

Он будет иметь те же ловушки, что и с одним ядром, но с дополнительной задержкой из-за синхронизации кэша L1, которая должна происходить между ядрами.

Примечание. «Вы можете сделать это без синхронизации» не всегда является верным утверждением.

5 голосов
/ 28 июня 2010

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

Для этого есть несколько причин:

  • ОС может прервать потокв любое время (между любыми двумя инструкциями), а затем запустите другой поток и
  • , если нет явной синхронизации, компилятор может очень упорядоченно переупорядочивать инструкции, нарушая любые гарантии, которые вы думалиу вас есть, и
  • даже процессор может делать то же самое, переупорядочивая инструкции на лету.

Если вы хотите корректную связь между двумя потоками, вам нужна какая-то синхронизация. Всегда , с без исключения.

Эта синхронизация может быть мьютексом, предоставляемым ОС или API потоков, или это могут быть специфичные для ЦП атомарные инструкции, илипросто простой барьер памяти.

1 голос
/ 28 июня 2010

Для неатомарной операции на многоядерном компьютере вам необходимо использовать систему Mutex, предоставленную для синхронизации доступа.

Для C ++ библиотека boost mutex предоставляет несколько типов мьютексов, которые обеспечивают согласованный интерфейс для типов мьютексов, предоставляемых ОС.

Если вы решите рассматривать boost как свою библиотеку синхронизации / многопоточности, вам следует ознакомиться с концепциями Synchronization .

0 голосов
/ 25 февраля 2011

Никто не упомянул о плюсах и минусах неявной синхронизации.

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

Основной «минус» в том, что это занимает много времени.Неявная синхронизация должна проходить через кеширование как минимум (как вы могли подумать) в первом кеше, который является общим для обоих ядер.Неправильно!На компьютере может быть установлено несколько физических процессоров, поэтому синхронизация не может остановиться в кеше, она должна идти до ОЗУ.Если вы хотите выполнить синхронизацию, вам также необходимо синхронизировать данные с другими устройствами, которые должны синхронизироваться с памятью, т. Е. С любым устройством управления шинами.Устройствами мастеринга шины могут быть карты на классической шине PCI, и они могут работать на частоте 33 МГц, поэтому неявная синхронизация должна будет подождать и их, чтобы подтвердить, что запись или чтение в определенном месте ОЗУ нормально.Мы говорим о 100-кратной разнице только в тактовой частоте между ядром и самой медленной шиной, а самой медленной шине требуется несколько собственных циклов шины для надежной реакции.Поскольку синхронизация ДОЛЖНА быть надежной, в противном случае она бесполезна.

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

Явными ключами синхронизации являются префикс LOCK и инструкция XCHG mem, reg.

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

0 голосов
/ 28 июня 2010

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

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

0 голосов
/ 28 июня 2010

В зависимости от вашей ситуации может иметь место следующее. Хотя это не заставит вашу программу работать неправильно, она может сильно повлиять на скорость. Даже если вы не обращаетесь к одной и той же ячейке памяти, вы можете получить снижение производительности из-за эффектов кэша, если два ядра перебирают одну и ту же страницу в кэше (хотя не в одном и том же месте, поскольку вы тщательно синхронизировали свои структуры данных).

Здесь есть хороший обзор "ложного обмена": http://www.drdobbs.com/go-parallel/article/showArticle.jhtml;jsessionid=LIHTU4QIPKADTQE1GHRSKH4ATMY32JVN?articleID=217500206

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