Совпадает ли установка бита с одновременными наборами других битов в том же слове? - PullRequest
4 голосов
/ 09 ноября 2010
  1. Скажем, у меня есть битовая карта, и несколько потоков (работающих на нескольких процессорах) устанавливают биты на ней. Синхронизация не используется и атомарные операции. Кроме того, перезагрузка не производится. Насколько я понимаю, когда два потока пытаются установить два бита в одном и том же слове, в конечном итоге останется только одна операция. Причина в том, что для установки бита все слово должно быть прочитано и записано обратно, и поэтому, когда обе операции чтения выполняются одновременно, при обратной записи одна операция переопределяет другую. Это правильно?

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

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

Ответы [ 3 ]

5 голосов
/ 09 ноября 2010

Короче говоря, это очень зависит от процессора и компилятора.

Скажем, у вас есть 32-битное значение, содержащее ноль, и поток A хочет установить бит 0, а поток B хочет установить бит 1.

Как вы описываете, это операции чтения-изменения-записи, и проблема синхронизации заключается в том, «что произойдет, если они сталкиваются».

Случай, который вам нужно избегать, таков:

A: Reads (gets 0)
B: Reads (also gets zero)
A: Logical-OR bit 0, result = 1
A: Writes 1
B: Logical-OR bit 1, result = 2
B: Writes 2 - oops, should have been 3

... когда правильный результат будет таким ...

A: Reads (gets 0)
A: Logical-OR bit 0, result = 1
A: Writes 1
B: Reads (gets 1)
B: Logical-OR bit 1, result = 2
B: Writes 3 - correct

На некоторых процессорах запись с изменением для чтения будет представлять собой три отдельные инструкции, поэтому вам потребуется синхронизация.На других это будет единственная атомарная инструкция.В системах с несколькими ядрами / процессорами это будет одна инструкция, но другие ядра / процессоры могут иметь к ней доступ, поэтому вам снова потребуется синхронизация.

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

Обновление для архитектуры X86 (и особенно для Windows)

Windows предоставляет набор элементарных «блокированных» операций над 32-разрядными значениями, включая Логическое ИЛИ .Это может помочь вам избежать критических разделов.но будьте осторожны, потому что, как указывает Раймонд Чен, они не решают все .Продолжайте читать этот пост, пока не поймете его!

2 голосов
/ 09 ноября 2010

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

1 голос
/ 09 ноября 2010
  1. Я полагаю, что это правда по указанным вами причинам.

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

...