Да нет же, это как раз правильный подход именно к мультитредовой синхронизации.
Слово volatile в C и C++ имело несколько другой смысл и для другого предназначалось - для прямой работы с железом, например. Ну и вот компилятор гарантирует, что каждое чтение-запись дойдёт до железа, и что относительный порядок волатильных чтений/записей будет как в коде (а все остальные чтения/записи могут прыгать как угодно вокруг, если это не меняет семантику).
Естественно, поверх такой абстракции можно и многотредовое взаимодействие сделать: тогда весь без исключения шаред стейт должен быть помечен как volatile (причём видимо любой доступ к полю волатильного поля тоже должен считаться волатильным).
Но это и неудобно программисту (легко что-нибудь забыть так пометить, а проверить никак невозможно), и как правило тормозит по сравнению с новой, заточенной специально под мультитредное взаимодействие концепцией: когда каждый синхронизационный примитив именно что синхронизирует всё состояние. Memory barrier ведь ничего не делает на самом деле, это просто запрет компилятору производить некоторые оптимизации. Зато позволяет проводить другие. В самом деле, вот есть у меня захват и освобождение мутекса, в новой модели компилятор не сможет перенести какие-то операции через эти два момента (причём скорее всего тех операций, которых я бы хотел разрешить перенести, не будет вовсе, например, потому что локальные переменные функции другим тредам недоступны по определению и на них запрет не распространяется), зато сможет как угодно тасовать и кешировать их внутри этих трёх кусков.
no subject
Date: 2009-03-16 04:01 pm (UTC)Слово volatile в C и C++ имело несколько другой смысл и для другого предназначалось - для прямой работы с железом, например. Ну и вот компилятор гарантирует, что каждое чтение-запись дойдёт до железа, и что относительный порядок волатильных чтений/записей будет как в коде (а все остальные чтения/записи могут прыгать как угодно вокруг, если это не меняет семантику).
Естественно, поверх такой абстракции можно и многотредовое взаимодействие сделать: тогда весь без исключения шаред стейт должен быть помечен как volatile (причём видимо любой доступ к полю волатильного поля тоже должен считаться волатильным).
Но это и неудобно программисту (легко что-нибудь забыть так пометить, а проверить никак невозможно), и как правило тормозит по сравнению с новой, заточенной специально под мультитредное взаимодействие концепцией: когда каждый синхронизационный примитив именно что синхронизирует всё состояние. Memory barrier ведь ничего не делает на самом деле, это просто запрет компилятору производить некоторые оптимизации. Зато позволяет проводить другие. В самом деле, вот есть у меня захват и освобождение мутекса, в новой модели компилятор не сможет перенести какие-то операции через эти два момента (причём скорее всего тех операций, которых я бы хотел разрешить перенести, не будет вовсе, например, потому что локальные переменные функции другим тредам недоступны по определению и на них запрет не распространяется), зато сможет как угодно тасовать и кешировать их внутри этих трёх кусков.