Оптимизация приложений .NET с использованием параллельного программирования

98

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

В наших статьях, посвященных оптимизации приложений .NET, мы бегло познакомимся с современной поддержкой параллельного программирования в .NET. Более подробно библиотека параллельного программирования (TPL - Task Parallel Library) описана в разделе "Потоки и файлы".

Перспективы и преимущества

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

Средние современные рабочие станции или мощные ноутбуки часто снабжаются мощными графическими процессорами (GPU), обладающими возможностью обслуживать сотни потоков выполнения. В дополнение к двум обычным приемам параллельного программирования появилась инфраструктура, предоставляемая как услуга (Infrastructure-as-a-Service, IaaS), с еженедельно снижающейся стоимостью использования, в лице которой вы в мгновение ока можете получить облачное окружение с несколькими тысячами ядер.

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

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

Как всегда, дорога к параллелизму полна ловушек - взаимоблокировки (deadlocks), состояния гонки (race conditions), «голодание» (starvation) и повреждение данных в памяти - поджидающих на каждом шагу. Новейшие параллельные фреймворки, включая библиотеки Task Parallel Library (.NET 4.0) и C++ AMP, которые мы будем использовать, стремятся уменьшить сложность разработки параллельных приложений и дать возможность извлечь максимальную выгоду в виде высокой производительности.

Зачем использовать приемы параллельного программирования?

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

Итак, после краткого рассмотрения перспектив параллельного программирования, давайте более подробно его рассмотрим.

Пройди тесты
Лучший чат для C# программистов