Обновить
2.95

Параллельное программирование *

Распараллеливаем вычисления

Сначала показывать
Порог рейтинга
Уровень сложности

RAII 2.0: RAII как архитектурный инструмент в C++

Уровень сложностиСредний
Время на прочтение7 мин
Количество просмотров5.6K

Идиома RAII — давно зарекомендовал себя как удобный способ автоматического управления ресурсами в C++. Обычно мы применяем его для управления памятью, файловыми дескрипторами или мьютексами. Однако что, если расширить понятие RAII до управления не только физическими ресурсами, но и логическими контрактами и состояниями системы?

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

Читать далее

Как я «ломал» DeepSeek

Время на прочтение10 мин
Количество просмотров13K

В своей предыдущей статье[1] я уже рассказывал, как начал свое знакомство с искусственным интеллектом (ИИ). Тогда это был ChatGPT, а теперь — китайский DeepSeek[2].

Общение с DeepSeek происходит без посредников, что делает его более удобным и доступным. Раньше за использование ChatGPT приходилось платить или, например,  задавать не более трёх вопросов в сутки. А с DeepSeek можно спрашивать сколько угодно и о чём угодно, не тратя ни копейки. Правда, есть опасения, что бесплатная подписка может закончиться, и тогда доступ к сервису будет закрыт. Также ходят слухи о возможных проблемах с «нежелательными» запросами.

Так уж жизнь повернулась, что для меня в автоматном программировании (АП) возникла пауза.  Но мне бросить АП все равно что перестать дышать. А потому просто произошла задержка дыхания или просто передышка. Меня это не сильно огорчило, т.к. я по-прежнему пользуюсь АП, вдыхая полной грудью его возможности. Даже в текущей ситуации.

Тем не менее, я кинулся, так сказать, «во все тяжкие». Мне предложили заняться «умными домами» и я согласился. Новая область, новые интересы, новое приложение своих сил. Короче, – «движуха»! Мы, ведь, все мечтаем о чем-то подобном – не так ли? А еще обещали мотивировать, что немаловажно в наше меркантильное время. Вспомним хотя бы размер виртуальной средней зарплаты по России и средний размер пенсий...

Сейчас я только рад случившемуся. Раньше было скучновато. Иногда взбадривало общение на Хабре, а теперь «поддает жару» искусственный интеллект. И хотя я предполагал что-то подобное, но не ожидал, что это произойдет столь быстро, так бурно и с таким эффектом. Китайский ИИ стал коллегой, советчиком, а, порой, и собеседником, помогая освоить новую область программирования. При этом я по-прежнему не согласен с глашатаями, предрекающими замену программистов, но уверен, что квалификацию многих из них он повысит точно. Я убедился в этом на своём опыте.

Читать далее

Метод Монте-Карло в алгоритме обратного распространения ошибок с параллельными вычислениями

Уровень сложностиСредний
Время на прочтение5 мин
Количество просмотров7.7K

Был проведён эксперимент для проверки, можно ли существенно уменьшить объём вычислений в алгоритме обратного распространения ошибок с параллельными вычислениями за счёт использования на каждом шаге обучения только части обучающих образцов, выбранных случайным образом, а также определение того, какой выигрыш по времени даст использование языка Ассемблера в самых внутренних циклах (в программе, написанной на языке C++).

За основу был взят классический персептрон и алгоритм обратного распространения ошибок, основанный на методе градиента, который объяснялся на курсе Mashine Learning Стэнфордского университета. Он был доработан, чтобы можно было использовать параллельные вычисления. Была написана программа на языке C++ для Linux, её функции (создание, обучение нейронной сети, распознавание данных, закачка больших файлов на сервер и т. п.) вызываются из программ, написанных на любых языках программирования, по протоколу Socket.

Для параллельных вычислений создаётся ntheads объектов нейронной сети, где ntheads — количество потоков (процессоров), в которые записываются части большого массива обучающих образцов, и на каждом шаге алгоритма обратного распространения ошибок совершается прямое и обратное распространение для каждого образца, имеющегося у объекта нейронной сети. Вычисления для каждого объекта производятся в отдельном потоке. Результатом этих вычислений являются суммарные градиенты слоёв сети каждого объекта, они суммируются друг с другом, и полученные градиенты используются для модификации матриц весов нейронной сети, которые затем прописываются во все слои сети объектов нейронной сети.

Читать далее

Многопоточность. Снизу вверх. Потоки в языке C#

Уровень сложностиСредний
Время на прочтение6 мин
Количество просмотров8.6K

Привет, Хабр! Это Дмитрий Бахтенков. Добро пожаловать в третью часть цикла статей «Многопоточность. Снизу вверх»! Мы уже разобрали процессор и операционную систему, а сегодня поговорим про использование потоков в .NET с помощью языка программирования C#.

Эта статья — обзор основных возможностей взаимодействия с потоками в .NET.

Читать далее

Параллельное программирование на Go

Уровень сложностиСредний
Время на прочтение21 мин
Количество просмотров8.2K

На практике, создаваемое нами ПО выполняется на множестве процессоров. К сожалению, многие наши допущения, справедливые для одного процессора, в случае нескольких процессоров становятся ложными. Например, каким будет состояние памяти, если два процессора изменяют один блок памяти? В общем случае на этот вопрос ответить сложно. Может случиться так, что внесённое одним процессом изменение перепишет внесённое другим. Справедливо может быть и обратное: может «победить» изменение другого процессора. Или оба процесса могут попытаться внести изменение одновременно, в результате чего возникнет неопределённое состояние, не соответствующее ни одному ожидаемому. Мы называем такие операции доступа «гонками данных» — ситуацией, в которой два или более процессоров в программе одновременно получают доступ к одной области памяти, и хотя бы одна из этих операций доступа выполняет запись без должной синхронизации.

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

Пример HTTP-сервера на PHP с использованием файберов. Улучшенная версия

Уровень сложностиСложный
Время на прочтение9 мин
Количество просмотров4K

В статье Пример HTTP-сервера на PHP с использованием файберов / Хабр краеугольным камнем организации обработки HTTP-соединений является функция socket_select(), которая имеет значительное ограничение - максимальное значение дескриптора, которое можно добавить в любой из трёх аргументов данной функции составляет 1024. Данный лимит определяется константой FD_SETSIZE, для увеличения которой придётся сконфигурировать системные лимиты и как минимум пересобрать интерпретатор PHP, что нецелесообразно и может создать эксплуатационные проблемы. К тому же, производительность функции select(), обёрткой над которой является функция socket_select(), значительно проседает при ощутимом увеличении значения константы FD_SETSIZE. В данной статье я постараюсь продемонстрировать альтернативу, позволяющую избавить пример из предыдущей статьи от данного ограничения.

Читать далее

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

Уровень сложностиСредний
Время на прочтение19 мин
Количество просмотров2.6K

Представьте себе: 2004 год, инженеры Intel готовятся к анонсу нового флагманского процессора Tejas. Семь гигагерц тактовой частоты — цифра, о которой разработчики могли только мечтать. И вдруг — неожиданное решение: проект отменен. Что произошло? Инженеры столкнулись с фундаментальным физическим барьером: тепловыделение и токи утечки делали дальнейшее наращивание частоты невозможным. Этот момент стал поворотным в истории вычислений.

«Мы достигли стены, — объявил тогда Патрик Гелсингер, технический директор Intel. — Будущее за параллелизмом».

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

Читать далее

3200% нагрузки на процессор

Уровень сложностиСредний
Время на прочтение15 мин
Количество просмотров19K

Совсем недавно моя машина была в таком запущенном состоянии, что я едва мог подключиться к ней через ssh. 3200% нагрузки на CPU — полностью использовались все 32 ядра хоста! Сравните это с моим последним багом, когда использовалось всего одно ядро, то есть 100%

К счастью, я использовал среду выполнения Java 17, у которой были дампы потоков с указанием времени CPU!

Читать далее

Параллелизм в Go тестах: все, что нужно знать о -p, -parallel и t.Parallel()

Уровень сложностиПростой
Время на прочтение2 мин
Количество просмотров1.9K

В Go есть три способа управления параллельностью тестов:

Короткий гайд о -p, -parallel и t.Parallel а также бонус для любителей параллельного программирования

Читать далее

А где память? Утечка goroutine и как ее пофиксить

Уровень сложностиСредний
Время на прочтение4 мин
Количество просмотров2.6K

Утечка горутин в Go происходит, когда горутина продолжает существовать и потреблять ресурсы, даже если она больше не выполняет полезной работы или не может завершиться. Это может произойти по разным причинам.
Мы рассмотрим 3 примера из которых: 2 будут на каналах, 1 с использованием mutex.

Читать далее

Спинлок в современном C++ с применением атомиков, барьеров памяти и экспоненциальной выдержкой

Время на прочтение9 мин
Количество просмотров5.4K
Эта статья послужит вам быстрым, но глубоким введением в низкоуровневую конкурентность.

Механизмы блокировки — важнейшая часть конкурентного программирования. Такие механизмы позволяют множественным потокам одновременно обращаться к разделяемым ресурсам, не мешая друг другу. Одна из самых популярных блокировок – это спинлок (циклическая блокировка), при которой применяется активное ожидание, механизм, позволяющий раз за разом проверять, не освободилась ли блокировка. Правда, при таком подходе будут тратиться драгоценные такты процессора, если блокировка зациклится и станет впустую потреблять ресурсы процессора. Для решения этой проблемы применяется подход под названием экспоненциальная выдержка. При экспоненциальной выдержке применяются постепенно нарастающие периоды ожидания, что позволяет не тратить ресурсы впустую.

В этой статье мы реализуем наш собственный упрощённый спинлок с экспоненциальной выдержкой. Для начала обсудим базовую идею, на которой основан спинлок — проблему активного ожидания. Затем разберём, что представляет собой экспоненциальная выдержка и обсудим, как повысить эффективность спинлоков. Затем поговорим об атомиках и о том, для чего они используются. После этого объясним, что представляют собой барьеры памяти, если они работают в тандеме. Далее рассмотрим образец реализации спинлока с экспоненциальной выдержкой, разберём достоинства и недостатки такого подхода. Наконец, напишем тестовую программу, которая поможет нам убедиться, что всё работает как надо. Начнём!
Читать дальше →

Гарантии видимости в распределённых хранилищах

Уровень сложностиСредний
Время на прочтение5 мин
Количество просмотров2.5K

Здравствуйте, меня зовут Дмитрий Карловский и я.. стараюсь сложные вещи рассказывать простым языком, а простые вещи — эзоповым. И часто оказывается так, что в процессе упрощения и структурирования, на самом видном месте обнаруживаются скелеты древних динозавров, присыпанные мутными формулировками так, что долгие годы их никто не замечает. Что ж, если вы хотите окончательно разобраться в уровнях изоляции транзакций и гарантиях порядка операций, до давайте копать вместе.

Выпускайте эскалатор!

Современные техники оптимизации производительности в C++. Кэш-локальность, аллокаторы и параллелизм

Уровень сложностиСредний
Время на прочтение5 мин
Количество просмотров8.8K

Как создать быстрый код на C++? Мы будем разбираться в современных техниках оптимизации: кэш-локальности, кастомных аллокаторах и многопоточности. Практические примеры и результаты тестов.

Читать далее

Ближайшие события

Безболезненная миграция с NATS на Kafka

Уровень сложностиСредний
Время на прочтение7 мин
Количество просмотров3.8K

Привет, Хабр! Меня зовут Максим, я Go-разработчик из Wildberries. Свою дебютную статью я хочу посвятить довольно популярной теме, когда на проекте приходится уходить с одной технологии на другую. Данная статья будет полезна разработчикам, кто активно использует асинхронный способ передачи данных в своих проектах.

Читать далее

Пример HTTP-сервера на PHP с использованием файберов

Уровень сложностиСложный
Время на прочтение15 мин
Количество просмотров9.9K

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

Читать далее

Чем отличается пессимистическая и оптимистическая блокировка в MySQL

Время на прочтение5 мин
Количество просмотров6.6K
При проектировании приложений, использующих базы данных, часто возникают такие ситуации, в которых требуется конкурентный доступ к данным. Это может приводить к самым разным последствиям, поскольку состояние базы данных может нарушиться, или некоторые данные могут быть потеряны. Чтобы предотвратить такие сценарии, существуют различные способы контролировать доступ к ресурсам. Например, применяется оптимистическая и пессимистическая блокировка, о которых мы здесь поговорим.
Читать дальше →

Глубокое погружение в базовую архитектуру LPU Groq

Уровень сложностиСредний
Время на прочтение14 мин
Количество просмотров2.1K

В этой статье мы собираемся разобрать архитектуру Tensor Streaming Processor TSP и его компилятора, а затем увидим, как Groq построили надежный и высокопроизводительный распределенный механизм инференса искусственного интеллекта с использованием этих TSP.

Читать далее

Ускорение LUP-разложения матрицы с помощью OpenCL

Уровень сложностиПростой
Время на прочтение5 мин
Количество просмотров1.5K

Я являюсь автором проекта по математическому моделированию прикладной механики и в работе моей программы до 90% вычислительного времени уходит на решение системы линейных уравнений. Цель этой статьи сугубо практическая - найти оптимальный метод решения системы линейных уравнений с точки зрения производительность/трудозатрат для небольшого проекта и рассказать о результате.

В прошлом я уже несколько раз обращал внимание на вычисления на GPU, но всегда что-то останавливало. И вот у меня накопился достаточный практический опыт программирования на C/C++ и наконец дошли руки, чтобы протестировать OpenCL.

Читать далее

Параллелизм и феномен ван дер Поля

Уровень сложностиСредний
Время на прочтение20 мин
Количество просмотров3.7K

Зачем нужны потоки, если есть параллелизм ВКПа? Поговорим об этом подробнее. По существу мы тем самым продолжим тему статьи[1], рассмотрев только более сложный пример, чем простые и абстрактные счетчики. Рассмотрим по ходу сначала пример, а уж потом и его реализацию на потоке.  Поехали?!

Читать далее

PARI/GP: как посчитать что-то просто, точно и параллельно

Уровень сложностиСредний
Время на прочтение12 мин
Количество просмотров3.8K


Мир изменился. Многоядерные процессоры повсюду. Использование их потенциала позволяет количество вычислительной мощи превратить в новое качество. Многие задачи стало выгодно численно решать и проводить эксперименты над ними.

В этой статье я расскажу о программе PARI, язык которой GP имеет очень низкий порог вхождения, примерно как Basic, но при этом позволяет проводить быстрые сверхточные целочисленные и вещественные вычисления (см. предыдущую статью). А большой свечкой на торте является то, что с её помощью можно совершенно элементарно загрузить все ядра ваших процессоров и серверов для получения максимально быстрого результата.

В этой статье за ~15 минут вы узнаете, как легко и просто загрузить компьютер на 100% вашими вычислительными задачами, даже если вы не являетесь профессиональным программистом.
Держу пари, вы не знали о PARI