Рубрика «параллельное программирование» - 28

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

Реализация не зависит от конечной платформы (.Net/Java), т.к. написана на C++/Asm, однако пользовательский код сделан на C#, т.к. на нем пишу я.

image

Теперь, когда я наконец стабилизировал пример для 32-разрядных систем, набравшись храбрости, готов показать его общественности как полностью готовый. И, да, повторюсь: при адаптации будет работать на любой платформе

Читать полностью »

Предисловие

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

За время работы в этой области у меня накопился некоторый опыт использования различных вычислительных технологий. На некоторые вопросы, которые могут быть интересны не только мне, я постараюсь отвечать в рамках этой публикации.
Читать полностью »

image

Работая над очередным игровым (обучающим) проектом ПЛИС для платы Марсоход2 я столкнулся с тем, что мне явно не хватает места в кристалле. Кажется и проект не очень сложный, но моя реализация такова, что требует много логики. В принципе, это ерунда, дело-то житейское. Ну, если очень будет нужно, то можно выбрать ПЛИС с большей емкостью. Собственно мой проект — это игра «Жизнь», но реализованная в ПЛИС на языке Verilog HDL.

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

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

Так вот. На моей плате стоит ПЛИС Cyclone III EP3C10E144C8 компании Альтера. 10тыс логических элементов. Сперва я думал, что смогу сделать двумерный массив клеток 128x64=8192 клетки. Не помещается. 64x64=4096 — то же не помещается в кристалл. Как же так. Я сумел вместить в ПЛИС только 32x16=512 клеток. Пичалька…

Размышления приводят меня к мысли, что возможно, в будущем, технология ПЛИС перерастет в нечто большее, чем программируемая логика. Вот об этом своем видении я хотел бы рассказать. Искушенному читателю сразу скажу, что многое далее написанное есть просто плод воображения и может быть даже бред.
Однако..Читать полностью »

image

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

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

Для ускорения выполнения задач желательно решить две проблемы:

  • Научить воркер не ждать выполнения каждого отдельного этапа задачи (асинхронность)
  • Научить воркер выполнять одновременно несколько задач (многопоточность) (disclaimer: на самом деле термин «многопоточность» тут используется в значении «многопроцессность»)

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

Параллельное программирование для начинающих на ЯП Elixir   Erlang VM на примере задачи «конь Эйлера»

Вступление

Чуть больше года назад я сделал очень важный в своей жизни поступок — скачал с сайта Microsoft IDE Visual Studio и написал на языке C++ свою первую в жизни программу, как это ни странно — «Hello, World!». За следующие полгода я прочитал небезызвестную книжку Страуструпа, устроился на работу джуниор С++ разработчиком, попробовал писать на Lua, Python, но каких-либо значительных успехов не добился — мои библиотеки не работали, программы с трудом компилировались и падали в runtime, указатели указывали не на те участки памяти (которая, кстати, всегда куда-то утекала), а попытки использовать больше одного потока (С++11 же!) приводили к порче памяти и дедлокам. О том, как выглядел код, лучше просто промолчать.

К чему это я? К тому, что по моему личному мнению/опыту императивные языки в силу своих особенностей совершенно не подходят начинающим разработчикам. Без знаний промышленных паттернов программирования, каких-то сведений о работе операционной системы и элементарной культуры кода написать что-то сносное на них очень тяжело. Они дают слишком много свободы и пространства для костылей и велосипедов, в то время как функциональные языки жёстко ограничивая разработчика в некоторых вещах оставляют ему не так много возможностей писать плохой код, заставляя думать и развиваться.

Примерно полгода назад я понял, что пора что-то менять, и после получаса поиска в интернете нашёл спецификации ЯП Erlang. В статье автор представлял Erlang как «чудесную таблетку» от всех вышеописанных мою проблем, и в общем-то по большей части он оказался прав. Так я начал программировать на Erlang, а затем и на Elixir.

Elixir Language

Elixir — язык, построенный поверх Erlang, результат компиляции — байткод Erlang VM. От Erlang он выгодно отличается простотой синтаксиса и мощным инструментарием для мета-программирования (люди, знакомые с Lisp сразу узнают quote-unquote конструкции). Соответственно, для использования доступен весь функционал Erlang, любые его модули и, что самое главное — фреймворк OTP.

Типы данных — те же самые, что и в Erlang. Данные — неизменяемые, результат действий с ними — новые данные. В Elixir как и во многих функциональных языках работает принцип «Всё — выражение». Любое выражение вернёт значение.

У ЯП Elixir есть отличный интерпретатор, который устанавливается вместе с языком, в нём можно опробовать примеры.
Читать полностью »

Этот цикл статей является вольным переводом книги «Rust by Example», которую пишет Хорхе Апарисио на Github.

На момент написания этого топика автор книги создал 49 глав, в первой части будет перевод первых пяти. Убедитесь, что Rust установлен и под рукой имеется документация.

Давайте начинать!
Читать полностью »

Данный пост является продолжением авторского перевода статьи «Flow Graphs, Speculative Locks, and Task Arenas in Intel® Threading Building Blocks» из Parallel Universe Magazine, выпуск 18, 2014. В этой половине статьи мы рассмотрим спекулятивные замки (speculative locks), которые используют преимущества технологии Intel® Transactional Synchronization Extensions и управляемые пользователем арены для задач (user-managed task arenas), которые обеспечивают расширенный контроль и управление уровнем параллелизма и изоляции задач. Если Вас заинтересовало — добро пожаловать под кат.
Читать полностью »

Как работает GIL в Ruby. Часть 3. Делает ли GIL ваш код потоко безопасным?

Переводы предыдущих двух частей:
Первая часть
Вторая часть

Это статья Jesse Storimer. Он выступает на семинаре Unix fu, онлайн классе для Ruby-разработчиков, которые хотят научиться удивительным хакам в Ruby и повысить свой уровень в разработке серверного стека. Количество участников ограничено, так что поторопитесь, пока есть свободные места. Так же, он является автором книг «Работа с Unix процессами», «Работа с TCP сокетами» и «Работа с потоками в Ruby».

В Ruby-сообществе существуют некоторые заблуждения относительно GIL в MRI-реализации интерпретатора. Если вы хотите узнать ответ на главный вопрос этой статьи, без ее прочтения, то вот он: GIL не делает ваш код на Ruby потоко-безопасным.

Но вы не должны принимать мои слова на веру.
Читать полностью »

Одним замечательным летним вечером, я в пылу спора имел глупость заметить, что можно написать быстро работающее решето Эратосфена на CUDA. N = 1000000000 (девять нулей) как цель. And the legend has begun…

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

#include <iostream>
#include <math.h>

using namespace std;

int main()
{
	double number = 1000000000;
	bool* a = new bool[int(number/2)];
	int i,j,result;

	for (i=0; i<number/2; i++)
		a[i] = true;

	for (i=3; i<=floor(sqrt(number)); i+=2)
		if (a[i/2])
			for (j=i*i; j<=number; j+=i*2)
				a[j/2]=false;

	result = 0;
	for (i=0; i<number/2; i++)
		if (a[i]) result++;

	cout << result << endl;

	delete[] a;

	return 0;
}

Однопоточный немного оптимизированный код, который работает на 14-15 секунд на Core i3 330M и затрачивает большое количество памяти. С него и начнем.
Читать полностью »

Данный пост является переводом статьи «Flow Graphs, Speculative Locks, and Task Arenas in Intel® Threading Building Blocks» из Parallel Universe Magazine, выпуск 18, 2014. Если вас интересует библиотека Intel® TBB в частности, и интересные современные концепции параллельного программирования в общем, то — добро пожаловать под кат.
Читать полностью »


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js