Marmot писал(а):Пока будет shared mutable state, будут и проблемы с локингом, какие модели ни применяй.
Реально существующих альтернатив пока две: pure functional programming without side effects(Haskell etc) и actor based approach (Erlаng, Scala etc)...
Первые подход намного более красивый, но абсолютно оторванный от реальной жизни.
При втором подходе есть риск опять наступить на те же грабли shared mutable state при неправильном использовании...
У нас пользуют job manager писанный самими. На самом деле, его в основном написали для относительно прозрачной поддержки ps3, но в процессе поняли, что он для симметричных многоядерных архитектур тоже хорошо подходит. Похоже отчасти и на functional programming, и на actor based, но насколько я могу судить, не совсем то. Лень разбираться в подробностях.
Его, правда, пока ни одна команда внутри EA правильно не использует, но это потому, что они тащат за собой кучу старого кода. Переписывать никому не хочется.
Там смысл в том, что никакого object sharing быть вообще не должно. Есть задачи, которые обращаются к менеджеру задач для организации себя в граф. Например, создаем задачу A и говорим, что она не может выполняться пока не завершатся задачи B и С. Задача D, в свою очередь должна выполниться по завершению задачи B. А задача E должна начаться после D и C. Соответственно, менеджер задач следит, чтобы мы не посадили циклической зависимости. Ну а потом выполняет с максимально возможным параллелизмом. Сначала B и C выполняются параллельно. Потом, по завершении B, параллельно с C запускается D. Потом, по завершении C, параллельно с D запускается A. А когда заканчивается D, параллельно с A выполняется E. Ну, понятно, в общем.
Идея состоит в том, что никаких ресурсов задачи не разделяют. Каждая работает со своими. А синхронизация перенесена от данных к порядку выполнения. То есть, менеджер задач заранее имеет всю картину синхронизации и действует максимально эффективно.
Работает хорошо. Нам на анимации удается добиться 80-90% загрузки SPU на PS3. А это очень хороший результат. Почти без простоя.
Программировать, правда не всегда удобно, но если привыкнуть, то все в порядке. Ну, например, у каждой задачи два хипа. Один локальный, один глобальный. Локальный пропадает когда задача завершается. Выделение в глобальном, естественно, вызывает старые добрые lock-и. А чтобы передавать его от задачи к задаче, приходится еще в конце добавлять специальную задачу для освобождения памяти. Но в целом, так жить можно. Надо просто мозги немного перестроить.