Одновременное обновление различных полей структуры - это безопасно? - PullRequest
4 голосов
/ 03 января 2011

Считайте, что у меня есть структура:

struct SimpleStruct {
    int x;
    int y;
    int z;
}

Теперь, если у меня есть 3 отдельных потока, каждый из которых обновляет только одно из полей x, y, z структуры соответственно, безопасно ли позволять им обновляться одновременно, или я должен использовать мьютекс или что-то, чтобы остановить это от происходит?

Ответы [ 6 ]

8 голосов
/ 03 января 2011

Это безопасно (структуры выровнены).

Однако вы должны быть осторожны с ложным разделением (см. статью Херба Саттера об этом): если поля находятся в одной строке кэша, записи будут эффективно сериализированы.

3 голосов
/ 03 января 2011

Вы можете безопасно обновить x из одного потока и y в другом, но вы не можете безопасно обновить x из 2 отдельных потоков без какой-либо синхронизации.

2 голосов
/ 03 января 2011

Как уже говорили многие, безопасно, если каждый поток обновляет только один из них (без коллизий) - ЕСЛИ у вас есть связный кеш. Если вы используете многопроцессорный процессор без когерентности кэша, все становится сложнее (и различаются в зависимости от того, нужна ли вам когерентность записи или когерентность чтения). Некоторым архитектурам может потребоваться процессор A для выполнения обратной записи в кэш, прежде чем процессор B сможет его увидеть. В зависимости от архитектуры, если A и B записывают в одну и ту же строку кэша, запись A может в редких случаях быть «потеряна» и перезаписана сбросом строки кэша записи B.

См., Например, проблемы когерентности DSP и ARM в процессорах DaVinci.

В большинстве случаев (связные кэши, потоки в одном и том же процессе и т. Д.) Это не проблема.

1 голос
/ 03 января 2011

x, y, z являются разными переменными и находятся в разных блоках памяти.Тот факт, что они сгруппированы в структуру, ничего не меняет.Можно безопасно обновлять x, y, z из нескольких потоков, если одна и та же переменная не обновляется несколькими потоками, а поток обновления не пытается читать из двух других переменных.Кроме того, остерегайтесь ложного обмена.Если обновление выполняется внутри замкнутого цикла, ложное совместное использование может сделать многопоточную реализацию медленнее, чем однопоточная.

1 голос
/ 03 января 2011

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

1 голос
/ 03 января 2011

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

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