C ++; вещи, чтобы заботиться в многоядерной среде - PullRequest
2 голосов
/ 17 января 2009

О чем следует помнить при кодировании в многоядерной среде?

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

т.е. Вместо того, чтобы

MyClass & GetInstance()
{

static Myclass singleMyclass;
return singleMyclass;
}

Лучше иметь

Myclass singleMyclass;

 MyClass & GetInstance()
    {

     return singleMyclass;
    }

GetInstance () может вызываться многими потоками одновременно.

Изменить:

Мой вопрос был о скрытых конструкциях c ++, о которых нужно знать при использовании их в многопоточных программах. В вышеупомянутом случае static не является потокобезопасным, поскольку компилятор добавляет некоторые инструкции для статических объектов, которые не являются потокобезопасными. Я ищу похожие конструкции, о которых нужно знать.

Ответы [ 4 ]

3 голосов
/ 17 января 2009

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

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

Второй подход является поточно-ориентированным, так как инициализация выполняется до создания каких-либо потоков (при условии, что ваши статические объекты не запускают потоки), но порядок или инициализация могут быть большой проблемой! Что если статический объект вызывает GetInstance () из своего конструктора до того, как будет создан экземпляр singleMyclass? (Подсказка: это не красиво!)

Я бы рекомендовал использовать первый подход, но прочтите Двойная проверка блокировки , но будьте осторожны, потому что на самом деле не работает

Обязательно прочитайте статью доктора Добба.

1 голос
/ 18 января 2009

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

Прекращение выполнения и барьеры памяти (или ограждения):

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

Наивным решением таких проблем является расширение области применения критических секций. Другой способ - использовать барьеры памяти или алгоритмы без блокировки.

0 голосов
/ 17 января 2009

Мне не терпелось ответить на этот вопрос, основываясь на его названии, но сейчас я не вижу его актуальности.

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

Для тех, кто работает с проектами на C ++, горячим предложением является библиотека Intel Threading Building Blocks book ). Он пытается убрать проблемы, скрывая их за шаблонными классами. Я думаю, что это делает довольно хорошую работу.

0 голосов
/ 17 января 2009

Multicore не так важен, так как вы можете получить несколько потоков в одноядерной системе.

Обе версии GetInstance () выглядят так, как будто они будут работать там, это методы класса, которые должны выполнять надлежащую блокировку и т. Д., Если они делают что-либо, что не является потокобезопасным.

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