<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Блоги &#187; yuryserdyuk</title>
	<atom:link href="http://software.intel.com/ru-ru/blogs/author/yuryserdyuk/feed/" rel="self" type="application/rss+xml" />
	<link>http://software.intel.com/ru-ru/blogs</link>
	<description></description>
	<lastBuildDate>Thu, 24 May 2012 12:16:29 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>C# 5.0 как язык параллельного программирования, или “Всё не так, ребята!”</title>
		<link>http://software.intel.com/ru-ru/blogs/2010/12/02/c-50/</link>
		<comments>http://software.intel.com/ru-ru/blogs/2010/12/02/c-50/#comments</comments>
		<pubDate>Thu, 02 Dec 2010 13:20:31 +0000</pubDate>
		<dc:creator>yuryserdyuk</dc:creator>
				<category><![CDATA[Параллельное программирование]]></category>
		<category><![CDATA[Разработка софта]]></category>
		<category><![CDATA[C# 5.0]]></category>
		<category><![CDATA[compiler]]></category>
		<category><![CDATA[асинхронные потоки]]></category>

		<guid isPermaLink="false">http://software.intel.com/ru-ru/blogs/2010/12/02/c-50/</guid>
		<description><![CDATA[В конце октября этого года компания Microsoft обнародовала <a href="http://msdn.microsoft.com/en-us/vstudio/async.aspx">Community Technical Preview (CTP) языка C# 5.0</a> . В некотором смысле, этот релиз можно считать революционным, поскольку именно в нем C# впервые стал, наконец-то, ЯЗЫКОМ параллельного программирования. Да, конечно, на нем можно было программировать параллельно и до этого, для чего требовалось использовать БИБЛИОТЕКУ потоков System.Threading. В C# 5.0 часть возможностей этой библиотеки перекрывают две новые конструкции: <strong><em>async </em></strong>и <strong><em>await</em></strong>, с помощью которых задается запуск параллельных (асинхронных) потоков и ожидание завершения их работы, соответственно.]]></description>
			<content:encoded><![CDATA[<p>В конце октября этого года компания Microsoft обнародовала <a href="http://msdn.microsoft.com/en-us/vstudio/async.aspx">Community Technical Preview (CTP) языка C# 5.0</a> . В некотором смысле, этот релиз можно считать революционным, поскольку именно в нем C# впервые стал, наконец-то, ЯЗЫКОМ параллельного программирования. Да, конечно, на нем можно было программировать параллельно и до этого, для чего требовалось использовать БИБЛИОТЕКУ потоков System.Threading.</p>
<p>В C# 5.0 часть возможностей этой библиотеки перекрывают две новые конструкции: <strong><em>async </em></strong>и <strong><em>await</em></strong>, с помощью которых задается запуск параллельных (асинхронных) потоков и ожидание завершения их работы, соответственно. Вот характерный пример их использования:</p>
<pre name="code" class="c-sharp">public static void Main(string[] args)
{        .   .   .
   while (true)
   {
     Console.WriteLine("Please input a number");
     number = int.Parse(Console.ReadLine());
     DoSum(1, number);
   }
}

public static async void DoSum(int from, int to)
{
   int result = await Sum(from, to);
   File.AppendAllText( ... result ...));
}

public static async Task&lt;int&gt; Sum(int from, int to)
{
 Task&lt;int&gt; sum = TaskEx.Run(() =&gt;
 {
   int result = 0;
   for (int i = from; i &lt;= to; i++)
   {
    // Simulate process delay.
    Thread.Sleep(500);
    result += i;
   }
   return result;
 });

 return await sum;
}</pre>
<p>Здесь, в главной программе запускается несколько асинхронных (параллельных) потоков DoSum, которые, в свою очередь, запускают дочерние асинхронные потоки Sum. Наконец, внутри Sum запускаются еще, на этот раз, безымянные потоки (в виде объектов типа Task).</p>
<p>Для иллюстративного примера такая тройная вложенность не очень хороша − можно было бы придумать что-нибудь и попроще, но нас в этом фрагменте будет интересовать другое, а именно, типы используемых выражений.</p>
<p>В частности, обратим внимание на присваивание</p>
<pre name="code" class="c-sharp">int result = await Sum(from, to);</pre>
<p>В корректной программе, типы правой и левой частей любого присваивания должны совпадать.<br />
Т.е., мы ожидаем, что выражение</p>
<pre name="code" class="c-sharp">await Sum(from, to);</pre>
<p>имеет тип int. Поскольку <strong><em>await</em></strong><strong><em> </em></strong>есть просто оператор ожидания завершения работы (асинхронной) функции Sum, то разумно предположить, что эта функция должна возвращать int. Смотрим в определение этой функции и<br />
видим, что тип возвращаемого ею значения есть Task&lt;int&gt; − однако, думаем мы сами про себя!<br />
Ладно, попробуем исправить ситуацию и предположим такое действие оператора <strong><em>await</em></strong>: если его аргумент имеет тип Task&lt;T&gt;, то сам оператор <strong><em>await</em></strong><strong><em> </em></strong>возвращает значение типа T − в этом случае, приведенное выше присваивание становится корректным относительно типов.</p>
<p>Но обратим теперь внимание на пару операторов из функции Sum</p>
<pre name="code" class="c-sharp">Task&lt;int&gt; sum = . . . ;
return await sum;
</pre>
<p>Здесь, по нашему предположению, оператор <strong><em>return</em></strong>, а следовательно, и функция Sum, должна возвращать значение типа int: смотрим на определение Sum и видим, что она возвращает значение типа Task&lt;int&gt; − приехали!</p>
<p>(Аналогичный разбор некорректностей в C# 5.0 можно найти <a href="http://gauravsmathur.wordpress.com/2010/11/04/something-wrong-with-async-await-and-the-tasktask/">здесь</a>).</p>
<p>В чем причины обнаруженного явления и какова вытекающая из всего этого мораль?</p>
<ol>
<li>Сами по себе конструкции <strong><em>async</em></strong><strong><em> </em></strong>и <strong><em>await</em></strong><strong><em> </em></strong>вполне обоснованы и являются частью асинхронной модели программирования, предложенной в языке <a href="http://research.microsoft.com/en-us/um/people/nick/polyphony/">Polyphonic C#</a> и далее использованной и развитой в языке <a href="http://www.mcsharp.net">MC#</a>.
<p>(Описание данной модели можно найти в одном из <a href="http://software.intel.com/ru-ru/blogs/2009/12/02/join/">постов</a> блога ISN).
</li>
<li>Конструкция <strong><em>await</em></strong><strong><em> </em></strong>не является универсальным средством синхронизации параллельных потоков, поскольку с ее помощью невозможно выразить некоторые более сложные схемы синхронизации, а потому разработчикам C# 5.0 и .NET пришлось оставить объекты типа Task со всеми сопутствующими им свойствами и методами.<br/>
</li>
<li>Полные средства параллельности в любом языке программирования можно обеспечить либо
</li>
<ol type="a">
<li> чисто языковыми средствами (например, <strong><em>async</em></strong>-методами, конструкциями <strong><em>channel</em></strong><strong><em> </em></strong>, <strong><em>handler</em></strong><strong><em> </em></strong>и связками, как в языке MC#), либо</li>
<li>с помощью библиотечных средств (например, Task Parallel Library в .NET 4.0)</li>
</ol>
<p>однако, их необдуманное скрещивание, как проиллюстрировано выше, может приводить к некорректностям.
</ol>
<p>Главный разработчик средств C# 5.0 Mads Torgersen из Microsoft основополагающий документ <a href="http://www.microsoft.com/downloads/en/details.aspx?FamilyID=d7ccfefa-123a-40e5-8ed5-8d2edd68acf4&amp;displaylang=en">“Asynchronous Programming in C# and Visual Basic”</a> (октябрь 2010г.) начинает словами:</p>
<blockquote><p>
“ …a developer doesn’t need to grapple with conceptual overhead, architectural impedance mismatch and leaky abstractions”.<br/><br />
(“ … Разработчик не должен бороться с концептуальными перехлестами, архитектурными несовместимостями и плохо продуманными абстракциями”).
</p></blockquote>
<p>Удивительно, насколько в точности до наоборот, эти слова описывают то, что сделано в C# 5.0 …</p>
<p>Тем не менее, попытка введения именно языковых средств параллельности (упомянутых конструкций <strong><em>async</em></strong><strong><em> </em></strong>и <strong><em>await</em></strong>) является прогрессивной тенденцией, поскольку такого рода средства позволяют писать компактные и понятные параллельные программы, имеющие строго определенную семантику. Еще один пример такого подхода − это язык <a href="http://golang.org/">Go</a> (см. также <a href="http://software.intel.com/ru-ru/blogs/2009/12/24/where-do-you-come-from-go/">пост</a>) компании Google. А потому настоящее параллельное программирование только начинается − я так думаю!</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/ru-ru/blogs/2010/12/02/c-50/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Новости из Китая: 7168* NVIDIA@Tesla + 14336*Intel Xeon = 2,5 петафлопа!</title>
		<link>http://software.intel.com/ru-ru/blogs/2010/10/28/7168-nvidiatesla-14336intel-xeon-25/</link>
		<comments>http://software.intel.com/ru-ru/blogs/2010/10/28/7168-nvidiatesla-14336intel-xeon-25/#comments</comments>
		<pubDate>Thu, 28 Oct 2010 13:46:49 +0000</pubDate>
		<dc:creator>yuryserdyuk</dc:creator>
				<category><![CDATA[Intel Software Network]]></category>

		<guid isPermaLink="false">http://software.intel.com/ru-ru/blogs/2010/10/28/7168-nvidiatesla-14336intel-xeon-25/</guid>
		<description><![CDATA[Суперкомпьютер "Tianhe-1A" достиг производительности в 2,5 петафлопа на тесте Linpack]]></description>
			<content:encoded><![CDATA[<p>Что-то меняется в царстве суперкомпьютинга - на передовые позиции среди фирм выходит NVIDIA, а среди стран - Китай. NVIDIA сегодня распространила <a href="http://pressroom.nvidia.com/easyir/customrel.do?easyirid=A0D622CE9F579F09&amp;version=live&amp;prid=678988&amp;releasejsp=release_157">пресс-релиз</a> о том, что построенный с ее помощью в Китае суперкомпьютер "Tianhe-1A" достиг производительности в 2,5 петафлопа на тесте Linpack. В релизе подчеркивается, что данная машина использует 7168 графических процессоров NVIDIA@Tesla M2050 на базе новейшей платформы Fermi, в которой резко улучшена производительность на числах типа double по сравнению с предыдущим поколением аналогичных GPU и где каждое GPU имеет 448 ядер. Предыдущий рекордсмен - машина Jaguar Cray XT-5 имеет производительность 1,75 петафлоп в секунду.</p>
<p>Кроме процессоров NVIDIA, "Tianhe-1A" имеет 14336 6-ядерных процессоров Intel Xeon. Энергопотребление нового суперкомпьютера - 4 мегаватта ( у Jaguar'а - почти 7 Мвт). Разработчики отмечают, что если бы машина такой производительности была бы построена только на обычных процессорах, то её бы энергопотребление составило 12 Мвт.</p>
<p>Китайская машина спроектирована в Национальном Университете оборонных технологий (National University of Defense Technology), а установлена в Национальном суперкомпьютерном центре в Тяньжине (Tianjin). Также подчеркивается (а это важно ввиду всем известным играм с включением машин в Top500), что данный суперкомпьютер является уже "fully operational". Предполагается, что эта машина будет системой с "открытым доступом" для проведения широкомасштабных научных вычислений. В этой связи остается только пожалеть, что к отечественному суперкомпьютеру "Ломоносов" (0,35 петафлоп) в МГУ, вроде бы запущенному в ноябре 2009 г., до сих пор нет доступа.</p>
<p>Подробности реализации теста Linpack с использованием GPU можно найти в статье Massimiliano Fatica "Accelerating linpack with CUDA on heterogeneous clusters".</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/ru-ru/blogs/2010/10/28/7168-nvidiatesla-14336intel-xeon-25/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Where do you come from, Go ?</title>
		<link>http://software.intel.com/ru-ru/blogs/2009/12/24/where-do-you-come-from-go/</link>
		<comments>http://software.intel.com/ru-ru/blogs/2009/12/24/where-do-you-come-from-go/#comments</comments>
		<pubDate>Thu, 24 Dec 2009 11:22:55 +0000</pubDate>
		<dc:creator>yuryserdyuk</dc:creator>
				<category><![CDATA[Параллельное программирование]]></category>

		<guid isPermaLink="false">http://software.intel.com/ru-ru/blogs/2009/12/24/where-do-you-come-from-go/</guid>
		<description><![CDATA[Одним из важных событий последних месяцев стало появление языка (параллельного) программирования Go от компании Google. Попробуем понять, откуда он взялся, что принес нового, каковы перспективы его продвижения в многомиллионные массы практикующих программистов…]]></description>
			<content:encoded><![CDATA[<p><a href="http://golang.org/"><img class="alignleft size-full wp-image-2002850" style="margin: 6px;" title="go-logo-black" src="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/go-logo-black.png" alt="" width="220" height="77" /></a>Хотим мы того или нет, но параллельная революция продолжается. Параллельное программирование, в частности, постепенно выруливает на некоторые магистральные пути, которые обещают быть перспективными.</p>
<p>Одним из важных событий последних месяцев стало появление языка (параллельного) программирования <a href="http://golang.org/">Go</a> от компании Google. Хотелось бы понять откуда он взялся, что принес нового, каковы перспективы его продвижения в многомиллионные массы практикующих программистов …</p>
<p>Во-первых, отметим, что данное новое средство параллельного программирования является языком, а не библиотекой с некоторым  API. Т.е., здесь предлагается всего несколько конструкций (в контексте Go, это всего, фактически, две конструкции − goroutines и channels), которые делают язык полноценным средством параллельного программирования. Таким образом, когорта современных языков, таких как <a href="http://x10.codehaus.org/">X10</a>, <a href="http://www.cilk.com/">Cilk++</a>, <a href="http://www.mcsharp.net/">MC#</a> и некоторые другие, пополнилась новым членом.</p>
<p>Во-вторых, язык Go имеет теоретическую модель, восходящую к “взаимодействующим последовательным процессам” Хоара (CSP − <a href="http://en.wikipedia.org/wiki/Communicating_sequential_processes">Communicating Sequential Processes</a>. Оттуда же, кстати, происходят и языки <a href="http://wotug.org/occam/">Occam</a> и <a href="http://ftp.sunet.se/pub/lang/erlang/">Erlang</a>).</p>
<p>Интересна следующая цитата авторов этого языка, в которой они отвечают на вопрос “Why build concurrency on the ideas of CSP?”, и, в более общем плане, почему параллельное программирование может быть сделано более простым (см. также по этой теме пост “<a href="http://software.intel.com/ru-ru/blogs/2008/12/10/389/">Параллельное программирование − это просто …</a>”):</p>
<blockquote><p>Concurrency and multi-threaded programming have a reputation for difficulty. We believe the problem is due partly to complex designs such as pthreads and partly to overemphasis on low-level details such as mutexes, condition variables, and even memory barriers. Higher-level interfaces enable much simpler code, even if there are still mutexes and such under the covers.</p></blockquote>
<p>Как известно (см. пост “<a href="http://software.intel.com/ru-ru/blogs/2009/12/02/join/">Join-модель параллельного программирования</a>”), каждое средство для параллельного программирования должно предоставлять конструкции для</p>
<ol>
<li>порождения параллельных процессов,</li>
<li>их взаимодействия между собой и</li>
<li>их синхронизации.</li>
</ol>
<p>Посмотрим (естественно, совсем кратко) что предлагает нам в этом отношении язык Go.</p>
<p><strong>Порождение параллельных процессов</strong></p>
<p>Конструкция запуска параллельного процесса имеет стандартный вид − вызов запускаемой функции снабжается специальным ключевым словом, указывающим, что исполнение этой функции должно происходить одновременно с исполнением запускаемой функции. Ключевое слово <strong><em>async</em></strong><strong><em> </em></strong>уже занято для этого в языках X10 и MC#, ключевое слово <strong><em>spawn</em></strong><strong><em> </em></strong>используется в Cilk++, поэтому здесь было выбрано слово <strong><em>go</em></strong>:</p>
<pre name="code" class="cpp:nogutter:nocontrols:">go  list.Sort();</pre>
<p>Функция, запущенная таким образом, называется <em>“</em><em>goroutine</em><em>”.</em> Goroutines являются легковесными (lightweight) сущностями, “укладываемыми” для исполнения в пул потоков.</p>
<p><strong>Взаимодействие параллельных процессов</strong></p>
<p>Ключевым понятием в Go, реализующим взаимодействие параллельных потоков, является понятие “канала” (channel). В связи с этим, интересна следующая цитата авторов языка, в которой, опять же, называются причины того, почему современное параллельное программирование является трудным, и предлагаются пути преодоления проблем:</p>
<blockquote><p>Concurrent programming in many environments is made difficult by the subtleties required to implement correct access to shared variables. Go encourages a different approach in which shared values are passed around on channels and, in fact, never actively shared by separate threads of execution. Only one goroutine has access to the value at any given time.</p></blockquote>
<p>Т.е., программирование на языке Go характеризуется слоганом:</p>
<blockquote><p>Do not communicate by sharing memory; instead, share memory by communicating.</p></blockquote>
<p>Здесь же заметим, что принцип <strong><em>“</em></strong><strong><em>share</em></strong><strong><em> </em></strong><strong><em>memory</em></strong><strong><em> </em></strong><strong><em>by</em></strong><strong><em> </em></strong><strong><em>communicating</em></strong><strong><em>”</em></strong>переносим и на случай распределенных вычислений − вычислений на кластере с теми же получаемыми преимуществами, которые отмечены в цитате.</p>
<p>Еще одна важнейшая вещь при использовании каналов для взаимодействия − это невозможность в принципе ситуации “data races”. В частности, отпадает необходимость использования для отладки тех частей, например, в Intel Parallel Inspector и PVS-Studio, которые ответственны за обнаружение такого рода ошибок. Таким образом,</p>
<blockquote><p>A high-level approach, using channels to control access, makes it easier to write clear, correct programs.</p></blockquote>
<p>Само понятие “канала” в параллельных языках имеет долгую историю. Оно изначально присутствует в математических исчислениях параллельных процессов, таких как CSP, <a href="http://en.wikipedia.org/wiki/Calculus_of_communicating_systems">CCS</a> и <a href="http://en.wikipedia.org/wiki/Pi_calculus">π-исчисление</a>, разработанных в 70-90-х годах прошлого века, а также в некоторых практических языках программирования того времени, например, в языке Occam.</p>
<p>В новой генерации средств параллельного программирования, это понятие является базовым в языке MC#, а также в библиотеке <a href="http://research.microsoft.com/en-us/um/people/crusso/joins/">Joins</a>).</p>
<p>В языке Go, каналы являются обычными объектами, создание которых выглядит, например, так:</p>
<pre name="code" class="cpp:nogutter:nocontrols:">c := make ( chan int, 100 );</pre>
<p>В этом фрагменте, создается канал <em>с</em>, по которому будут передаваться целые числа, с емкостью внутренней очереди этого канала равной 100 сообщениям (целым числам).</p>
<p>Передача данных по каналу выглядит как</p>
<pre name="code" class="cpp:nogutter:nocontrols:">c &lt;- 2;</pre>
<p>а прием данных из канала оформляется как</p>
<pre name="code" class="cpp:nogutter:nocontrols:">int  x := &lt;- c;</pre>
<p>Отметим, что в языке Go по каналам могут передаваться только одиночные значения, тогда как в MC# по каналам могут посылаться произвольные <em>n</em>-ки значений.</p>
<p>Наконец, каналы в Go, как обычные объекты могут передаваться в качестве аргументов функций, в том числе, и goroutines, а также пересылаться по другим каналам (channels of channels). Типичная ситуация передачи канала в качестве аргумента goroutine − это использование этого канала для передачи сигнала о завершении работы параллельной функции:</p>
<pre name="code" class="cpp">	func  compute ( i, n int, c chan int )
	{
		for  ;  i &lt; n; i++ {
		{
		   . . .
		}
		c &lt;- 1; // signal that work is done
	}</pre>
<p><strong>Синхронизация параллельных процессов</strong></p>
<p>Предыдущий пример уже был иллюстрацией использования каналов как средства синхронизации − одна функция ждет сообщения от другой функции, чтобы продолжить свою работу. И, действительно, каналы являются базовым средством синхронизации в языке Go (в дополнение к их основной функции передачи значений между процессами). А суть механизма синхронизации лежит в ограниченности внутренней очереди канала: если она полностью заполнена, то процесс, пытающийся послать очередное сообщение по данному каналу, заблокируется.</p>
<p>В частности, если канал имеет размер внутренней очереди равный 0 (так называемый “небуферизованный” или “синхронный” канал), то процесс, посылающий значение по каналу, заблокируется до момента выдачи некоторым другим процессом команды чтения из этого канала. Таким образом, как пишут авторы языка Go</p>
<blockquote><p>Channels combine communication − the exchange of values − with synchronization …</p></blockquote>
<p>В языке MC# каналы являются буферизованными с неограниченным размером буфера. Это позволяет решать часть задач синхронизации именно с помощью каналов, а решение остальных задач синхронизации обеспечивают связки (chords).</p>
<p>Отметим также важную дополнительную конструкцию синхронизации языка Go − конструкцию <strong><em>select</em></strong>:</p>
<pre name="code" class="cpp">	select {
		case   request := &lt;- service:
			go run ( request );
		case    &lt;- quit:
			return;
	}</pre>
<p>Здесь, оператор <strong><em>select</em></strong><strong><em> </em></strong>реализует ожидание прихода сообщения по одному из двух каналов − <em>service</em><em> </em>или <em>quit</em>, выполняя, соответственно, либо обслуживание запроса, либо выход из обработки.</p>
<p>Заканчивая краткое описание параллельных средств языка Go, необходимо отметить, что авторы языка почему-то отказались от строгого проведения в жизнь ими же провозглашенного принципа отказа от низкоуровневых средств контроля доступа к разделяемым переменным.</p>
<p>В частности, в языке (точнее, в пакете <em>sync</em>, прилагаемом к языку) присутствует понятие “мьютекса”, а именно, 2 типа мьютексов: <em>sync</em><em>.</em><em>Mutex</em><em> </em><em>и </em><em>sync</em><em>.</em><em>RWMutex</em><em> </em>с довольно сложной семантикой их работы. Как, например, вам понравится , в частности, такое описание их работы:</p>
<blockquote><p>For any call to l.RLock on a sync.RWMutex variable l, there is an n such that the l.RLock happens (returns) after the n'th call to l.Unlock and the matching l.RUnlock happens before the n+1'th call to l.Lock.</p></blockquote>
<p>PS</p>
<p>Хочу поздравить всех с наступающим 11111011010 годом ! Новогоднюю открытку я не предусмотрел, но, по традиции, в качестве подарка хочу сделать ссылку на альбом электронной музыки “<a href="http://warp.net/records/general/2010-compilation">2010</a>” от лэйбла Warp.</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/ru-ru/blogs/2009/12/24/where-do-you-come-from-go/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Join-модель параллельного программирования</title>
		<link>http://software.intel.com/ru-ru/blogs/2009/12/02/join/</link>
		<comments>http://software.intel.com/ru-ru/blogs/2009/12/02/join/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 13:41:59 +0000</pubDate>
		<dc:creator>yuryserdyuk</dc:creator>
				<category><![CDATA[Intel Software Network]]></category>
		<category><![CDATA[Академическое сообщество]]></category>
		<category><![CDATA[Параллельное программирование]]></category>
		<category><![CDATA[Разработка софта]]></category>

		<guid isPermaLink="false">http://software.intel.com/ru-ru/blogs/2009/12/02/join/</guid>
		<description><![CDATA[В этой заметке речь пойдет как о самой, указанной в заголовке, модели, так и о ее воплощении в практических языках программирования. Один из примеров такого языка − Concurrent Basic от Microsoft, другие примеры см. ниже. Join-модель параллельного программирования опирается на строгий математический базис − π-исчисление параллельных процессов, разработанное Р.Милнером, а точнее, на один из его [...]]]></description>
			<content:encoded><![CDATA[<p>В этой заметке речь пойдет как о самой, указанной в заголовке, модели, так и о ее воплощении в практических языках программирования. Один из примеров такого языка − <a href="http://software.intel.com/ru-ru/blogs/2009/04/07/basic-concurrent-basic/">Concurrent Basic</a> от Microsoft, другие примеры см. ниже.</p>
<p>Join-модель параллельного программирования опирается на строгий математический базис − <a href="http://en.wikipedia.org/wiki/Pi_calculus"><span style="&quot;Times New Roman&quot;;">π</span>-исчисление параллельных процессов</a>, разработанное Р.Милнером, а точнее, на один из его вариантов, а именно, <a href="http://en.wikipedia.org/wiki/Join-calculus">join</a><a href="http://en.wikipedia.org/wiki/Join-calculus">-исчисление</a>. Указанная математическая модель является универсальной в том смысле, что она может быть реализована в рамках различных парадигм программирования − как функциональной, так и императивной (объектно-ориентированной(ОО)). Примерами функциональных языков, основанных на join-модели, являются <a href="http://jocaml.inria.fr/">JoCaml</a> и <a href="http://lamp.epfl.ch/funnel/">Funnel</a>; примеры ОО-языков − <a href="http://research.microsoft.com/en-us/um/people/nick/polyphony/">Polyphonic C</a><a href="http://research.microsoft.com/en-us/um/people/nick/polyphony/">#</a>, <a href="http://research.microsoft.com/en-us/um/cambridge/projects/comega/">Cω</a>, <a href="http://en.wikipedia.org/wiki/Join_Java">JoinJava</a>, <a href="http://www.mcsharp.net">MC</a><a href="http://www.mcsharp.net">#</a>.Ниже попытаюсь наглядно объяснить существенные, и они же оригинальные, черты данного подхода к параллельному программированию.</p>
<p>Каждый язык или иное средство (библиотека, набор “прагм” и т.д.) параллельного программирования должны иметь три обязательных компоненты, превращающих их в универсальный инструмент для такого программирования; а именно, средства для</p>
<ol>
<li>порождения параллельных процессов,</li>
<li>взаимодействия этих процессов между собой и</li>
<li>их синхронизации.</li>
</ol>
<p>В распространенных на данный момент ОО-языках, используются для этих целей низкоуровневые механизмы, такие как</p>
<ol>
<li>потоки,</li>
<li>разделяемая память (переменные) и</li>
<li>различные блокирующие конструкции (locks, mutexes,мониторы, семафоры и т.п.).</li>
</ol>
<p>Причем, в большинстве случаев, заметим это особо, эти механизмы доступны через API библиотек, имеющих большое количество разнообразных функций. Основная идея join-модели − это дополнить язык программирования минимальным, но достаточным набором параллельных конструкций, исключающих необходимость использования каких-либо библиотек указанного типа (в частности, вплоть до библиотеки System.Threading в .NET). В рамках ОО-парадигмы, это означает, что мы пытаемся расширить (последовательный) ОО-язык программирования естественными для него конструкциями, превращающими его в параллельный язык. Как это достигается в конкретных языках? Пройдемся по всем тем трем компонентам, которые были перечислены выше.</p>
<p><strong><em>Порождение параллельных процессов</em></strong></p>
<p>Одной из базовых конструкций в ОО-языке является функция/метод. В обычном последовательном языке методы являются синхронными − исполнение вызвавшей функции блокируется до тех пор, пока вызванный метод не завершит свою работу. Естественный способ сделать ОО-язык параллельным − это ввести в дополнение к синхронным двойственные им “асинхронные” методы, вызов которых завершается фактически мгновенно, а исполнение которых происходит одновременно с исполнением вызвавшего метода. Чтобы определить метод как асинхронный, пометим его специальным ключевым словом, например, <strong><em>async</em></strong>:</p>
<pre class="cpp:nogutter:" name="code">public async Compute ( int x, double y )
{
           .  .  .
}</pre>
<p>(Заметим, что ключевое слово <strong><em>async</em></strong><strong><em> </em></strong>стоит на месте типа возвращаемого значения, поскольку асинхронные методы в данной модели не возвращают значений). Отметим также, что мы превратили (пока частично) язык в параллельный, не привлекая таких дополнительных, и я бы их назвал “ортогональными” к ОО-подходу, понятий, как поток (thread), задача (task) и т.п., поскольку в данном подходе они оказываются ненужными. Асинхронные методы рассчитаны на “локальный параллелизм”, т.е., такие методы запускаются локально на одном из ядер многоядерной машины. В случае распределенной конфигурации − кластера или Grid-сети, эту идею можно обобщить: для возможного запуска метода на другой машине, достаточно пометить его в качестве “перемещаемого” (<strong><em>movable</em></strong>) метода, как это сделано в языке MC#. Использование только ключевого слова <strong><em>async</em></strong> для таких случаев недостаточно, поскольку для запуска метода на удаленной машине необходимо решать специфические проблемы, например, проблемы сериализации/десериализации передаваемых данных. Опять же, если конфигурация машины является специфической, например, гибридной с двумя типами процессорных ядер, как в случае процессора Cell, то для запуска метода на процессоре определенного типа (например, на SPE в Cell) его надо пометить соответствующим ключевым словом (в MC# методы, предназначенные для запуска на SPE-элементах Cell, помечаются модификатором <strong><em>spe</em></strong>). Заметим, что единая асинхронная модель программирования здесь сохраняется для всех типов параллельных архитектур, а потому, в случае использования, например, кластера с многоядерными узлами нет необходимости “скрещивать ежа с ужом” − OpenMP с MPI.</p>
<p><strong><em>Взаимодействие параллельных процессов между собой</em></strong></p>
<p>В обычных языках параллельного программирования взаимодействие процессов чаще всего происходит через общую память (разделяемые переменные), что требует привлечения блокирующих средств типа locks, mutexes и т.п. Кроме того, известно, что взаимодействие процессов по такому принципу − один из главных источников ошибок в параллельных программах. Для сохранения единой модели программирования как в локальном, так и в распределенном вариантах, а также для исключения использования низкоуровневых блокирующих средств, в join-модели программирования взаимодействие параллельных процессов происходит с использованием простого и интуитивного понятного понятия “канала”, в который можно данные посылать и из которого можно эти данные принимать. Например, канал по которому передаются тройки разнотипных чисел может быть объявлен следующим образом:</p>
<pre class="cpp:nogutter:" name="code">public channel c ( int x, float y, Complex z )
{
    .  .  .
}</pre>
<p>Фактически получается, что “каналы” − это еще один вид методов, правда, оператор вызова которых несколько отличается от общепринятого по синтаксису</p>
<pre class="cpp:nogutter:" name="code">
c ! ( 100, 0.1f, new Complex ( 2.0, -1.5 ) );
</pre>
<p>Принять данные из канала можно с помощью тех же средств, которые обеспечивают синхронизацию параллельных процессов в join-модели.</p>
<p><strong><em>Средства синхронизации параллельных процессов</em></strong></p>
<p>Средством синхронизации в join-модели являются так называемые “связки” (chords). Здесь, как и в случае синхронных и асинхронных методов, нам понадобится еще одно обобщение ОО-языка − будем считать, что метод, который обычно состоит из заголовка (сигнатуры) и вычислительного тела, теперь может иметь несколько заголовков. Соответственно, инструкции тела метода могут начать исполняться только тогда, когда произойдет вызов для всех заголовков этого метода − именно здесь оказывается скрытым механизм синхронизации join-модели. Заметим, что вызов нескольких заголовков принципиально возможен потому, что, в общем случае, вычисления происходят в многопоточной среде. Типичным примером связки (в языке MC#) является связка, состоящая из канала и обработчика, где последний предназначен для получения данных из ассоциированного с ним канала:</p>
<pre class="cpp:nogutter:" name="code">public class Buffer
{
  public handler Get string() &amp; public channel Put ( string s )
  {
   return s;
  }
}</pre>
<p>Принцип работы связки очевиден: если вызван обработчик, а данные в канал еще не поступили, то этот вызов будет заблокирован (до момента появления данных в канале). При поступлении данных в канал, когда обработчик еще не вызван, данные сохраняются во внутренней очереди канала. Легко понять, что низкоуровневые механизмы запирания и синхронизации здесь скрыты под более высокоуровневыми понятиями канала, обработчика и связки.</p>
<p>Ниже представлен пример связки, используемой для реализации барьерной синхронизации в известной программе вычисления чисел Фибоначчи:</p>
<pre class="cpp:nogutter:" name="code">public handler Get2 int() &amp; channel c1 ( int x ) &amp; channel c2 ( int y )
{
            return  x + y;
}</pre>
<p>Здесь вызов обработчика Get2 будет заблокирован до тех пор, пока по каналам c1 и c2 не придут соответствующие значения, которые будут просуммированы в теле связки.</p>
<p>Важным свойством каналов и обработчиков, сближающих их с "делегатами" (<strong><em>delegates</em></strong>) языка C#, является то, что они могут передаваться в качестве аргументов другим методам, включая <strong><em>async</em></strong>- и <strong><em>movable</em></strong>-методы. В частности, можно посылать каналы и обработчики по каналам и принимать их с помощью обработчиков. Всё это вместе позволяет организовывать произвольные схемы взаимодействия между параллельными, распределенными процессами.</p>
<p>Резюме будет коротким: добавив полдесятка конструкций (ср. с количеством функций в OpenMP, Intel TBB, Microsoft PFX, MPI et al.), мы превратили обычный ОО-язык программирования в универсальный язык для параллельного программирования.</p>
<p>В качестве заключения, хочу предложить, по традиции, две задачи:</p>
<p>1. Каналы и обработчики не являются обычными объектами; в частности, для них не предусмотрены конструкторы и они не могут участвовать в операциях присваивания. Однако, в некоторых задачах возникает ситуация, когда главная программа получает от процесса-потомка канал, который ей необходимо как-то сохранить, чтобы в дальнейшем иметь возможность многократно посылать данные по нему процессу-потомку.</p>
<p>Тем не менее, данную ситуацию легко смоделировать с помощью некоторой связки, обеспечивающей прием канала от процесса-потомка и дальнейшее многократное использование этого канала для передачи значений. Как может выглядеть эта связка?</p>
<p>2. Какой из современных языков программирования, не упомянутый выше, также использует концепцию каналов для взаимодействия параллельных процессов между собой и допускает, в частности, передачу каналов по каналам?</p>
<p>PS</p>
<p>На сайте <a href="http://www.intuit.ru/">Интернет-университета информационных технологий </a>недавно опубликован учебный курс <a href="http://www.intuit.ru/department/supercomputing/ppmcp/">“Параллельное программирование для многоядерных процессоров”</a>, в котором рассматриваются Microsoft PFX и MC#.</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/ru-ru/blogs/2009/12/02/join/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Китайское искусство программирования 2, или 9,58 vs 22,317,699,616,364,044</title>
		<link>http://software.intel.com/ru-ru/blogs/2009/08/31/2-958-vs-22317699616364044/</link>
		<comments>http://software.intel.com/ru-ru/blogs/2009/08/31/2-958-vs-22317699616364044/#comments</comments>
		<pubDate>Mon, 31 Aug 2009 13:25:55 +0000</pubDate>
		<dc:creator>yuryserdyuk</dc:creator>
				<category><![CDATA[Intel Software Network]]></category>
		<category><![CDATA[Академическое сообщество]]></category>
		<category><![CDATA[Параллельное программирование]]></category>
		<category><![CDATA[Разработка софта]]></category>

		<guid isPermaLink="false">http://software.intel.com/ru-ru/blogs/2009/08/31/2-958-vs-22317699616364044/</guid>
		<description><![CDATA[Продолжим о задаче N-Queens, поскольку, как я упомянул в первой части данного поста (его можно прочитать здесь), 2009-й год оказался прорывным в ее решении. Параллельный вариант решения этой задачи можно получить элементарным образом: если мы зафиксируем первого ферзя в самом верхнем ряду, в первой клетке слева, то нахождение всех расстановок остальных ферзей можно поручить одному [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/usain_bolt.jpg"><img class="alignleft size-medium wp-image-2002056" src="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/usain_bolt-300x225.jpg" alt="" width="300" height="225" /></a>Продолжим о задаче N-Queens, поскольку, как я упомянул в первой части данного поста (его можно прочитать <a href="http://software.intel.com/ru-ru/blogs/2009/07/29/2001817/">здесь</a>), 2009-й год оказался прорывным в ее решении.</p>
<p>Параллельный вариант решения этой задачи можно получить элементарным образом: если мы зафиксируем первого ферзя в самом верхнем ряду, в первой клетке слева, то нахождение всех расстановок остальных ферзей можно поручить одному процессору. Аналогично, если зафиксировать первого ферзя в этом же ряду во второй клетке слева, то отыскание всех возможных расстановок оставшихся ферзей можно поручить другому процессору. Ну и т.д.</p>
<p>В общем случае, для подходящего числа M ( M &lt; N, где N − размер доски) можно найти все допустимые расстановки ферзей в первых M рядах, применив всё ту же функцию <em>Backtrack</em> на основе битовых векторов (см. код, приведенный в первой части). Множество таких расстановок можно считать совокупностью (очередью) заданий для решателей, каждый из которых запускается на отдельном процессоре. Подсчет количества вариантов расстановок оставшихся N-M ферзей решатели производят, снова пользуясь базовой функцией <em>Backtrack</em>. Полный код программы на языке MC#, реализующий такой подход, и предназначенный для исполнения на многоядерной машине, приведен ниже.</p>
<pre name="code" class="cpp:collapse">using System;

public class Task   {

 public int left, down, right;

 public Task ( int l, int d, int r ) {

  left  = l;
  down  = d;
  right = r;

 }

}

//**************************************************//

public class NQueens   {

 public static long totalCount = 0;

 public static void Main ( String[] args ) {

  int   N = System.Convert.ToInt32 ( args [ 0 ] );   //  Board size
  int   M = System.Convert.ToInt32 ( args [ 1 ] );   //  Number of fixed queens
  int   P = System.Convert.ToInt32 ( args [ 2 ] );   //  Number of workers

  NQueens nqueens = new NQueens();

  nqueens.launchWorkers ( N, M, P, nqueens.getTask, nqueens.sendStop, nqueens );

  nqueens.generateTasks ( N, M, P, nqueens.sendTask );

  for ( int i = 0; i &lt; P; i++ )
   nqueens.getStop ? ();

  Console.Write     ( "Task challenge : " + N + "   " );
  Console.WriteLine ( "Solutions = " + totalCount );

 }

 //******************************************************************************//

 public handler getTask Task(int count ) &amp; channel sendTask ( Task task ) {

  totalCount += count;
  return ( task );

 }

 //******************************************************************************//

 public handler getStop void() &amp; channel sendStop () {
  return;
 }

 //******************************************************************************//

 public async launchWorkers ( int N, int M, int P, handler Task(int) getTask,
                              channel () sendStop, NQueens nqueens            ) {

  for ( int i = 0; i &lt; P; i++ )
   nqueens.Worker ( i, N, M, getTask, sendStop );

 }

 //******************************************************************************//

 public void generateTasks ( int N, int M, int P, channel (Task) sendTask ) {

  int   y     = 0;
  int   left  = 0;
  int   down  = 0;
  int   right = 0;

  int   MASK  = ( 1 &lt;&lt; N ) - 1;

  MainBacktrack ( y, left, down, right, MASK, M, sendTask );

  Task finish_marker = new Task ( -1, -1, -1 );

  for ( int i = 0; i &lt; P; i++ )
   sendTask ! ( finish_marker );

 }

 //********************************************************************************//

 public void MainBacktrack ( int y, int left, int down, int right, int MASK,
                             int M, channel (Task) sendTask                  ) {

  int   bitmap, bit;

  if ( y == M )
   sendTask ! ( new Task ( left, down, right ) );
  else   {

   bitmap = MASK &amp; ~ ( left | down | right );

   while ( bitmap != 0 )   {

    bit   = -bitmap &amp; bitmap;
    bitmap = bitmap ^ bit;

    MainBacktrack ( y + 1, ( left | bit ) &lt;&lt; 1, down | bit, ( right | bit ) &gt;&gt; 1,

                    MASK, M, sendTask                                            );

   }

  }

 }

 //********************************************************************************//

 public async Worker ( int myNumber, int N, int M, handler Task(int) getTask,

                  channel () sendStop                                    ) {

  int    MASK  = ( 1 &lt;&lt; N ) - 1;

  int    count = 0;

  Task   task  = (Task) getTask ? ( count );

  while ( task.left != -1 )   {

   WorkerBacktrack ( M, task.left, task.down, task.right, MASK, N, ref count );

   task  = (Task) getTask ? ( count );
   count = 0;

  }

  sendStop ! ();

 }

 //********************************************************************************//

 public void WorkerBacktrack ( int y, int left, int down, int right, int MASK,

                               int N, ref int count                           ) {

  int   bitmap, bit;

  if ( y == N )
   count++;
  else   {

   bitmap = MASK &amp; ~ ( left | down | right );

   while ( bitmap != 0 )   {

    bit   = -bitmap &amp; bitmap;
    bitmap = bitmap ^ bit;

    WorkerBacktrack ( y + 1, ( left | bit ) &lt;&lt; 1, down | bit, ( right | bit ) &gt;&gt; 1,
                    MASK, N, ref count                                             );

   }

  }

 }

}</pre>
<p>Специфическая особенность языка MC# заключается в том, что для того, чтобы получить из данной программы распределенный вариант для исполнения на кластере, достаточно заменить пометку параллельной функции <em>Worker</em><em> </em>c <strong><em>async</em></strong> на <strong><em>movable</em></strong>. Также, данный код программы без изменений работает как под Windows, так и под Linux.</p>
<p>А причем здесь какие-то странные числа, вынесенные в заголовок, можете спросить вы? Ну, про 9,58 многие уже догадались … А вот ко второму числу подойдем чуть издалека …</p>
<p>Относительно задачи N-Queens можно задаться вопросом − для доски какого максимального размера мы можем её решить, т.е., подсчитать количество всех возможных расстановок? Оказывается, этот размер не так уж и велик. Впервые, решение для N = 24 было получено в 2004 г. (точнее, 11 апреля 2004 г.). Количество решений составило</p>
<p><strong><em>227 514 171 973 736 </em></strong></p>
<p>(см. отчет “<a href="http://www.arch.cs.titech.ac.jp/~kise/doc/paper/uec-is-2004-06.pdf">Solving the 24-queens problem using MPI on a PC Cluster</a>”). Решение для N = 25 не заставило себя долго ждать − оно было получено 11 июня 2005 г. и составило</p>
<p><strong><em>2 207 893 435 808 352</em></strong></p>
<p>Для получения решения было использовано 260 машин и счет продолжался более 6 месяцев (см. <a href="http://proactive.inria.fr/index.php?page=nqueens25">http://proactive.inria.fr/index.php?page=nqueens25</a>). Трудоемкость этой задачи оценивается в более, чем 50 лет работы одного компьютера.</p>
<p>С тех пор, данная задача несколько раз использовалась в соревнованиях по Grid-вычислениям (см., например, <a href="http://www.etsi.org/plugtests/grid/IVGRID_PLUGTESTS.htm">http://www.etsi.org/plugtests/grid/IVGRID_PLUGTESTS.htm</a>), а результат для N = 25 оставался до недавнего времени рекордом.</p>
<p>С середины прошлого года для нас стали доступны мощные кластеры, появившиеся в России – “CКИФ-МГУ” (5000 ядер, МГУ) и МВС-100К (7920 ядер, Межведомственный суперкомпьютерный центр РАН). Возникло естественное желание попытаться решить эту задачу для N = 26. Дополнительным стимулом к этому стала попытка решить эту задачу в проекте NQueens @Home (<a href="http://nqueens.ing.udec.cl/"><span style="Times New Roman;">http://nqueens.ing.udec.cl/</span></a><strong><span style="Times New Roman;">) </span></strong>на основе системы распределенных вычислений BOINC, с помощью которой можно объединить для решения обычные PC с установленными на них специальными клиентскими программами. Данный проект стартовал в августе 2008 г.</p>
<p>Вначале мы просто проверили работоспособность системы MC# на большом количестве процессоров − результаты обнадежили. Вот протокол решения задачи для N = 21 на кластере “СКИФ-МГУ” на 4200 ядрах:</p>
<div style="padding: 6px; background-color:#cfcfcf; width: 350px;">
<p>MC#.Runtime, v. 2.1.0.34023</p>
<p>Task challenge : 21 Solutions = 314666222712</p>
<p>==MC# Statistics================================</p>
<p>Number of movable calls: 4200</p>
<p>Number of channel messages: 87108</p>
<p>Number of movable calls (across network): 4200</p>
<p>Number of channel messages (across network): 4200</p>
<p>Total time: 00:02:55.3579270 / 175.357927 sec.</p></div>
<p>В качестве базового алгоритма был взят алгоритм на основе битовых векторов, но использующий симметрии (см. <a href="http://www.ic-net.or.jp/home/takaken/e/queen/index.html">http://www.ic-net.or.jp/home/takaken/e/queen/index.html</a>). Оказалось, что этот алгоритм возможно распараллелить в соответствии с подходом, упомянутым выше. Более того, для N = 26 задача на самом верхнем уровне удачно разбивается на 277 независимых частей, каждую из которых можно считать в виде отдельного задания на кластере. И 18 ноября 2008 г. счет начался … Он проходил обычной ручной постановкой очередного задания на тот или кластер. Трудоемкость нескольких особо сложных заданий превысила 30 000 процессоро-часов.</p>
<p>Просчет заданий шел не так быстро как хотелось бы, поскольку оба кластера всегда перегружены работой − иногда в очередях стоит 100−200 заданий. Но, тем не менее, проект NQueens@Home нам удалось догнать очень быстро − на сегодняшний день он вышел лишь за 50% выполнения всей задачи.</p>
<p>Однако, в этом деле нашелся свой Усэйн Болт <img src='http://software.intel.com/ru-ru/blogs/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  . Когда, в конце июля этого года мы начали приближаться к завершению нашего счета, то обнаружили в Интернете ссылку вот на этот вот сайт − <a href="http://queens.inf.tu-dresden.de/?l=en&amp;n=0">http://queens.inf.tu-dresden.de/?l=en&amp;n=0</a>. Оказалось, что в рамках проекта Queens@TUD 11 июля 2009 г. было получено решение для N = 26:</p>
<p><strong><em>22 317 699 616 364 044</em></strong></p>
<p>Но получено оно было на основе принципиально иной технологии. Немецкие специалисты воспользовались для решения задачи технологией на основе FPGA, что по-русски звучит как ПЛИС (программируемые логические интегральные схемы). Т.е., другими словами, они построили специализированную многопроцессорную вычислительную машину, которая предназначена для решения одной единственной задачи – задачи N-Queens. Правда, и счет у них начался раньше, чем у нас − 14 октября 2008 г. Схема их решателя и была приведена на картинке в 1-ой части этого поста.</p>
<p>Ну а что мы? Наш счет закончился 30 августа 2009 г., и мы лишь порадовались тому, что результат полностью совпал с полученным немецкими компьютерщиками; т.е., и сам результат верифицировали, и удостоверились что наша программа была корректной. Код программы, результаты и полные протоколы запусков скоро будут выставлены на нашем сайте <a href="http://www.mcsharp.net/">www.mcsharp.net</a>.</p>
<p>Какие выводы можно сделать из этой истории? Наверно, один из них состоит в том, что системы на базе FPGA будут вне конкуренции для получения рекордных результатов в решении отдельно взятых задач. С другой стороны, появились упоминания о попытках решения этой задачи на GPU. C третьей стороны, наличие кластеров хотя бы с 20 000 ядрами позволит и с помощью этих универсальных средств посоревноваться в решении специальных счетных задач.</p>
<p>Другие выводы и свои мысли по этому поводу можно оставлять в комментариях. Интересно, сможет ли кто-нибудь правильно спрогнозировать когда будет получено решение этой задачи для N = 27 ?</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/ru-ru/blogs/2009/08/31/2-958-vs-22317699616364044/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Китайское искусство программирования</title>
		<link>http://software.intel.com/ru-ru/blogs/2009/07/29/2001817/</link>
		<comments>http://software.intel.com/ru-ru/blogs/2009/07/29/2001817/#comments</comments>
		<pubDate>Wed, 29 Jul 2009 12:23:48 +0000</pubDate>
		<dc:creator>yuryserdyuk</dc:creator>
				<category><![CDATA[Intel Software Network]]></category>
		<category><![CDATA[Параллельное программирование]]></category>
		<category><![CDATA[Разработка софта]]></category>

		<guid isPermaLink="false">http://software.intel.com/ru-ru/blogs/2009/07/29/2001817/</guid>
		<description><![CDATA[Те, кто интересовался Intel Threading Challenge 2007-2008 и Intel Threading Challenge 2009 , наверно, заметили активное участие в них и, самое главное, отличные результаты программистов из Китая. Регулярно борются они за первые места и на чемпионатах мира по программированию (ACM ICPC). Причем, теперь уже по моим личным наблюдениям, с ними совершенно невозможно соперничать в классических [...]]]></description>
			<content:encoded><![CDATA[<p>Те, кто интересовался <a href="http://softwarecontests.intel.com/threadingchallenge/">Intel Threading Challenge 2007-2008 </a>и <a href="http://software.intel.com/en-us/contests/Threading-Challenge-2009/codecontest.php">Intel Threading Challenge</a><a href="http://software.intel.com/en-us/contests/Threading-Challenge-2009/codecontest.php"> 2009</a> , наверно, заметили активное участие в них и, самое главное, отличные результаты программистов из Китая. Регулярно борются они за первые места и на чемпионатах мира по программированию (<a href="http://cm.baylor.edu/welcome.icpc">ACM ICPC</a>). Причем, теперь уже по моим личным наблюдениям, с ними совершенно невозможно соперничать в классических задачах программирования, таких как, например, сортировки, поиск и др. Однако, кроме великолепного знания методов решения стандартных задач, не откажешь им и в креативности. Вот показательный пример на эту тему …</p>
<p><img class="alignleft" src="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/nqueens1.jpg" alt="" width="241" height="246" /></p>
<p>Наверняка, всем хорошо известна <a href="http://en.wikipedia.org/wiki/Eight_queens_puzzle">задача о расстановке ферзей </a>на шахматной доске таким образом, чтобы они взаимно не били друг друга. Суть задачи, а точнее, ее обобщения состоит в том, чтобы подсчитать количество всех возможных таких расстановок на доске размером N x N (NQueens Problem). Удивительно то, что хотя самой задаче уже около 150 лет, но существенный прорыв в ее решении произошел совсем недавно, в 2002 г. (а еще один прорыв состоялся в июле 2009г., но об этом позже). </p>
<p><em>(Прежде чем читать дальше, тем, кто никогда не пробовал самостоятельно запрограммировать решение этой задачи, настоятельно рекомендуется попытаться сделать собственную реализацию.)</em></p>
<p>И автором этого прорыва, как вы уже, наверно, догадались, стал человек из Китая по имени Qiu Zongyan из Пекинского университета (его <a href="http://portal.acm.org/citation.cfm?id=568613">статья</a> помещена в журнале ACM SIGPLAN Notices). </p>
<p>Поскольку алгоритм решения задачи представляет собой, в сущности, полный перебор, то, чтобы сделать его максимально быстрым, нужно эффективным образом организовать структуры данных, отображающие текущую конфигурацию ферзей на доске с тем, чтобы потратить минимальное число операций на переход к следующей конфигурации.</p>
<p>Суть гениального по своей простоте приема, предложенного Qiu Zongyan, проиллюстрируем на примере.</p>
<p>Предположим, что в алгоритме ферзи выставляются на доску по порядку, начиная с самой верхней горизонтали. Например, после расстановки двух первых ферзей мы можем иметь следующую конфигурацию на двух первых горизонталях доски 8&nbsp;x&nbsp;8:</p>
<table width="400" border="0" cellspacing="0" cellpadding="16">
<tr align="center" >
<td align="left" width="100">&nbsp;</td>
<td>0</td>
<td>0</td>
<td>Ф</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr align="center">
<td align="left" width="100">&nbsp;</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>Ф</td>
<td>0</td>
<td>0</td>
</tr>
</table>
<p></p>
<p>Теперь, чтобы вычислить допустимые позиции на третьей горизонтали, нам нужно определить какие из позиций на этой горизонтали находятся под боем ранее выставленных ферзей; а именно, какие позиции принадлежат</p>
<p>1) диагоналям, по которым выставленные ферзи бьют справа-налево,</p>
<p>2) вертикалям, по которым ферзи бьют сверху-вниз,</p>
<p>3) диагоналям, по которым ферзи бьют слева-направо. </p>
<p>Представим эти позиции, находящиеся под боем (отметив их единичками) в виде соответствующих трех битовых векторов: </p>
<table width="400" border="0" cellspacing="0" cellpadding="16">
<tr align="center">
<td align="left" width="100">left:</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
</tr>
<tr align="center">
<td align="left" width="100">down:</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>0</td>
</tr>
<tr align="center">
<td align="left" width="100">right:</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
</tr>
</table>
<p></p>
<p>Поэлементно складываем все эти вектора логически по ИЛИ и получаем занятые/свободные позиции на третьей горизонтали: </p>
<table width="400" border="0" cellspacing="0" cellpadding="16">
<tr align="center">
<td align="left" width="100">&nbsp;</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>1</td>
<td>0</td>
</tr>
</table>
<p></p>
<p>Итак, у нас имеется 3 возможных способа поставить очередного ферзя. Выбираем, например, вторую позицию слева и ставим туда третьего ферзя.</p>
<p>А теперь – <strong>внимание !</strong> – ключевой момент алгоритма. Как нам получить новую конфигурацию доски, а именно, занятые позиции теперь уже на четвертой горизонтали? А делаем всего лишь вот что − ставим единицу во вторую позицию (т.е., позицию, куда мы поставили нового ферзя) каждого из векторов left, down и right, и </p>
<p> a) сдвигаем вектор left влево на 1 бит (вычисляем позиции под боем на диагоналях, идущих от уже поставленных ферзей справа-налево),</p>
<p> б) ничего не делаем с down,</p>
<p> в) сдвигаем вектор right вправо на 1 бит (аналогично пункту а, но для диагоналей слева-направо).</p>
<p>Суммируем чего мы добились − мы представили конфигурации ферзей на доске в виде битовых векторов, а их модификацию выразили исключительно через битовые операции. </p>
<p>Остальная часть алгоритма − это обычный бектрекинг с целью получения всех возможных расстановок. Полное решение этой задачи на языке C# представлено ниже.</p>
<pre name="code" class="cpp">
using System;
public class NQueens   {
 public static int Backtrack(int y, int left, int down,
 int right, int N, int MASK)
 {
     int  bitmap, bit;
     int  count = 0;
     if (y == N) {
         return ( 1 );
     } else {
         bitmap = MASK &#038; ~(left | down | right);
         while (bitmap != 0) {
             bit = -bitmap & bitmap;
             bitmap ^= bit;
             count += Backtrack(y+1,(left | bit)&lt;&lt;1, down | bit,
             (right | bit)>>1, N, MASK);
         }
         return ( count );
     }
 }
 public static void Main(String[] args )
 {
     int N    = Convert.ToInt32 ( args [ 0 ] );
     int MASK = (1 &lt;&lt; N) - 1;
     int result = Backtrack(0, 0, 0, 0, N, MASK);
     Console.WriteLine ("N=" + N + " -> " + result);
 }
}
</pre>
<p>Схема параллелизации этого алгоритма не так интересна − она очевидна, и, похоже, единственна. О ней и о сопутствующих результатах, я надеюсь, мы поговорим в планирующемся продолжении этого поста. А пока лишь упомяну, что детальное описание приведенного выше алгоритма вместе со схемой параллелизации на <a href="http://www.mcsharp.net">языке </a><a href="http://www.mcsharp.net">MC</a><a href="http://www.mcsharp.net">#</a>  можно будет вскоре найти в учебном курсе “Параллельное программирование для многоядерных процессоров”, который будет размещен на сайте <a href="http://www.intuit.ru/">Интернет-университета информационных технологий</a> и на сайте <a href="http://www.microsoft.com/Rus/Msdnaa/Curricula/Default.mspx">Microsoft MSDN Academic Alliance</a> . Варианты решения этой же задачи с использованием OpenMP и Intel TBB можно найти в документе <a href="http://www.xlsoft.com/en/products/intel/parallel/files/NQueens_samples.pdf">“</a><a href="http://www.xlsoft.com/en/products/intel/parallel/files/NQueens_samples.pdf">Parallelizing N-Queens with the Intel Parallel Composer</a><a href="http://www.xlsoft.com/en/products/intel/parallel/files/NQueens_samples.pdf">”</a> , а с использованием Cilk++ - <a href="http://www.cilk.com/multicore-blog/bid/6381/Multicore-enabling-the-N-Queens-Problem-Using-Cilk">здесь</a>. </p>
<p>В заключении, по традиции две загадки − как вы думаете, что это такое? </p>
<p>1)</p>
<pre name="code" class="cpp">
  int t(int a, int b, int c){
     int d=0, e=a&#038;~b&#038;~c, f=1;
     if (a)
       for (f=0; d=(e-=d)&-e;)
         f+=t(a-d,(b+d)*2,(c+d)/2);
     return f;
  }
  int main( int argc, char *argv[]) {
    int q = atoi ( argv [ 1 ] );
    printf("%d\n",t(~(~0&lt;&lt;q),0,0));
  }
  </pre>
<p>2)</p>
<p><img src="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/tud09_2.jpg" alt="" width="500" height="427" /></p>
<p>Ответы − в следующем посте.</p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/ru-ru/blogs/2009/07/29/2001817/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Начинаем программировать на Basic ... Concurrent Basic</title>
		<link>http://software.intel.com/ru-ru/blogs/2009/04/07/basic-concurrent-basic/</link>
		<comments>http://software.intel.com/ru-ru/blogs/2009/04/07/basic-concurrent-basic/#comments</comments>
		<pubDate>Tue, 07 Apr 2009 13:00:29 +0000</pubDate>
		<dc:creator>yuryserdyuk</dc:creator>
				<category><![CDATA[Intel Software Network]]></category>
		<category><![CDATA[Академическое сообщество]]></category>
		<category><![CDATA[Параллельное программирование]]></category>
		<category><![CDATA[Разработка софта]]></category>

		<guid isPermaLink="false">http://software.intel.com/ru-ru/blogs/2009/04/07/basic-concurrent-basic/</guid>
		<description><![CDATA[На международной конференции по объектно-ориентированному программированию OOPSLA’2008, состоявшейся в г. Нэшвилл, шт. Теннесси, США, октябрь 2008г., фирма Microsoft анонсировала расширение языка Visual Basic 9.0 под названием Concurrent Basic (CB). В некоторых изданиях, CB уже охарактеризовали как “возможное будущее направление, по которому пойдет развитие Visual Basiс”. В чем же тут дело?  Более точно, на вышеупомянутой конференции был [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="small;"><span style="Times New Roman;"><span style="bold;">На международной конференции по объектно-ориентированному программированию </span><span style="EN-US;" lang="EN-US">OOPSLA</span><span style="bold;">’2008, состоявшейся в г. Нэшвилл, шт. Теннесси, США, октябрь 2008г., фирма </span><span style="EN-US;" lang="EN-US">Microsoft</span><span style="bold;"> анонсировала расширение языка </span><span style="EN-US;" lang="EN-US">Visual</span><span style="bold;" lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Basic</span><span style="bold;"> 9.0 под названием </span><a href="http://channel9.msdn.com/shows/Going+Deep/Claudio-Russo-and-Lucian-Wischik-Inside-Concurrent-Basic"><span style="EN-US;" lang="EN-US">Concurrent</span><span style="bold;" lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Basic</span></a><span style="bold;"><a href="http://channel9.msdn.com/shows/Going+Deep/Claudio-Russo-and-Lucian-Wischik-Inside-Concurrent-Basic"> </a>(</span><span style="EN-US;" lang="EN-US">CB</span><span style="bold;">). В некоторых изданиях, </span><span style="EN-US;" lang="EN-US">CB</span><span style="bold;"> уже охарактеризовали как “возможное будущее направление, по которому пойдет развитие </span><span style="EN-US;" lang="EN-US">Visual</span><span style="bold;" lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Basi</span><span style="bold;">с”. В чем же тут дело?</span></span></span><span style="EN-US;" lang="EN-US"><span style="Times New Roman;"> </span></span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="small;"><span style="Times New Roman;"><span style="bold;">Более</span><span style="EN-US;"> </span><span style="bold;">точно</span><span style="EN-US;" lang="EN-US">, </span><span style="bold;">на</span><span style="EN-US;"> </span><span style="bold;">вышеупомянутой</span><span style="EN-US;"> </span><span style="bold;">конференции</span><span style="EN-US;"> </span><span style="bold;">был</span><span style="EN-US;"> </span><span style="bold;">представлен</span><span style="EN-US;"> </span><span style="bold;">доклад</span><span style="EN-US;" lang="EN-US"> <a href="http://research.microsoft.com/en-us/um/people/crusso/">Claudio Russo </a></span><span style="bold;">из</span><span style="EN-US;" lang="EN-US"> Microsoft Research (Cambridge, United Kingdom) </span><span style="bold;">под</span><span style="EN-US;"> </span><span style="bold;">названием</span><span style="EN-US;" lang="EN-US"> “<a href="http://research.microsoft.com/en-us/um/people/crusso/papers/cb.pdf">Join patterns for Visual Basic</a>”. </span><span style="bold;">Базовые идеи этого доклада представляет следующий абзац:</span></span></span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="EN-US;" lang="EN-US"><span style="Times New Roman;">"</span></span><a href="http://research.microsoft.com/en-us/projects/concurrentbasic/default.aspx" target="_blank"><span style="EN-US;" lang="EN-US"><span style="Times New Roman;">Concurrent Basic</span></span></a><span style="EN-US;" lang="EN-US"><span style="small;"><span style="Times New Roman;"> extends Visual Basic with stylish asynchronous concurrency constructs derived from the join calculus. Our design advances earlier Microsoft Research work on Polyphonic C#, Comega and the Joins Library.”</span></span></span><span style="EN-US;" lang="EN-US"><span style="Times New Roman;"> </span></span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="Times New Roman;">В данном абзаце перечислены некоторые названия, которые, скорее всего, мало знакомы или совсем незнакомы практикующим программистам (хотя некоторые из них уже были отмечены в одном из моих предыдущих постов, см. <a href="http://software.intel.com/ru-ru/blogs/2008/12/12/123-larrabee/">здесь</a> </span><span style="Times New Roman;">).</span><span style="Times New Roman;"> </span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="small;"><span style="Times New Roman;">История же эта началась с <span style="EN-US;" lang="EN-US">FOOL</span> 9 :-)</span><span style="Times New Roman;"> - 9-ой международной конференции “<span style="EN-US;" lang="EN-US">Foundations</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">of</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Object</span>-<span style="EN-US;" lang="EN-US">Oriented</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Languages</span>” (январь 2002г.), на которой, опять же, люди из <span style="EN-US;" lang="EN-US">Microsoft</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Research</span>, а именно, <span style="EN-US;" lang="EN-US">Nick</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Benton</span>, <span style="EN-US;" lang="EN-US">Luca</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Cardelli</span>, С<span style="EN-US;" lang="EN-US">edric</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Fournet</span> предложили новую модель асинхронного (читай, параллельного) программирования, базирующуюся на определенной формальной математической модели – <a href="http://en.wikipedia.org/wiki/Join-calculus"><span style="EN-US;" lang="EN-US">join</span>-исчислении</a></span></span><span style="Times New Roman;">.</span><span style="Times New Roman;"> </span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="Times New Roman;">Языки программирования, на самом деле, являются довольно консервативной областью – всё здесь, или, почти всё, уже изобретено, а потому появление новой замечательной модели есть вещь неординарная. Сам математический формализм – <span style="EN-US;" lang="EN-US">join</span>-исчисление – по своей сути, не ориентирован на какой-либо конкретный язык программирования, а потому применим как к функциональным, так и к императивным/объектно-ориентированным языкам. Результатами такого применения среди функциональных языков являются языки <a href="http://jocaml.inria.fr/"><span style="EN-US;" lang="EN-US">Jocaml</span> </a> и <a href="http://lamp.epfl.ch/funnel/"><span style="EN-US;" lang="EN-US">Funnel</span></a>, а соответствующими расширениями объектно-ориентированных языков <span style="EN-US;" lang="EN-US">Java</span><span lang="EN-US"> </span>и <span style="EN-US;" lang="EN-US">C</span># стали <a href="http://en.wikipedia.org/wiki/Join_Java"><span style="EN-US;" lang="EN-US">Join</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Java</span> </a>и <a href="http://research.microsoft.com/en-us/um/people/nick/polyphony/"><span style="EN-US;" lang="EN-US">Polyphonic</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">C</span>#</a></span><span style="Times New Roman;">. Последний из названных языков стал впоследствии частью языка <a href="http://research.microsoft.com/en-us/um/cambridge/projects/comega/">С<span style="EN-US;" lang="EN-US">omega</span></a>, другая часть которого известна сегодня как <span style="EN-US;" lang="EN-US">LINQ</span>.</span><span style="EN-US;" lang="EN-US"><span style="Times New Roman;"> </span></span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="Times New Roman;">Новая предложенная модель хоть и отличается от концепций параллелизма, имевшихся до сих пор, на самом деле, не так уж и сложна. Тем не менее, компания <span style="EN-US;" lang="EN-US">Microsoft</span><span lang="EN-US"> </span>из языка <span style="EN-US;" lang="EN-US">Comega</span><span lang="EN-US"> </span>внедрила поначалу в практику только <span style="EN-US;" lang="EN-US">LINQ</span>, а в качестве средства параллельного программирования предложила еще одну реинкарнацию концепции потоков – библиотеку <a href="http://en.wikipedia.org/wiki/Parallel_FX_Library"><span style="EN-US;" lang="EN-US">Task</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Parallel</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Library</span> </a>(<span style="EN-US;" lang="EN-US">TPL</span>)</span><span style="Times New Roman;">. Возможно, что в этом случае <span style="EN-US;" lang="EN-US">Microsoft</span><span lang="EN-US"> </span>посчитала, что программистское сообщество не готово к переходу на концептуально новый параллельный язык программирования, предложив ему еще одну библиотеку.</span><span style="Times New Roman;"> </span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="Times New Roman;">Однако, появление <span style="EN-US;" lang="EN-US">Concurrent</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Basic</span><span lang="EN-US"> </span>свидетельствует о том, что <span style="EN-US;" lang="EN-US">Microsoft</span>, возможно, всё-таки начала внедрять эту модель, зайдя со стороны <span style="EN-US;" lang="EN-US">Basic</span>’а – воспримет ли новые идеи, для начала, <span style="EN-US;" lang="EN-US">Basic</span>-сообщество?</span><span style="EN-US;" lang="EN-US"><span style="Times New Roman;"> </span></span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="Times New Roman;">О самих ключевых идеях <span style="EN-US;" lang="EN-US">Concurrent</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Basic</span>’а планирую рассказать в ближайших моих постах. В частности, на <span style="EN-US;" lang="EN-US">CB</span><span lang="EN-US"> </span>имеется реализация известной игры Конвэя “Жизнь”, которая являлась одним из заданий конкурса <a href="http://softwarecontests.intel.com/threadingchallenge/"><span style="EN-US;" lang="EN-US">Intel</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Threading</span><span lang="EN-US"> </span><span style="EN-US;" lang="EN-US">Challenge</span> 2008</a></span><span style="Times New Roman;">. Решение всех заданий этого конкурса на языке <span style="EN-US;" lang="EN-US">MC</span>#, который также принадлежит к группе языков, базирующихся на <span style="EN-US;" lang="EN-US">join</span>-исчислении, включены в дистрибутив новой версии <a href="http://www.mcsharp.net"><span style="EN-US;" lang="EN-US">MC</span># 2.1</a>.</span></p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/ru-ru/blogs/2009/04/07/basic-concurrent-basic/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>“Параллельное программирование – это просто” 2, или “The most general definition of beauty”</title>
		<link>http://software.intel.com/ru-ru/blogs/2008/12/23/2-the-most-general-definition-of-beauty/</link>
		<comments>http://software.intel.com/ru-ru/blogs/2008/12/23/2-the-most-general-definition-of-beauty/#comments</comments>
		<pubDate>Tue, 23 Dec 2008 16:42:28 +0000</pubDate>
		<dc:creator>yuryserdyuk</dc:creator>
				<category><![CDATA[Intel Software Network]]></category>

		<guid isPermaLink="false">http://software.intel.com/ru-ru/blogs/2008/12/23/2-the-most-general-definition-of-beauty/</guid>
		<description><![CDATA[В заголовок этого поста вынесено начало эпиграфа к книге K.Mani Chandy, Jayadev Misra “Parallel Program Design: A Foundation”. Полностью этот эпиграф выглядит так: “The most general definition of beauty … Multeity in Unity” (Samuel Taylor Coleridge, “On the Principles of Genial Criticism”, 1814). К чему это? Хотелось бы еще на одном примере показать, как грамотно [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/parallel_program_design.jpg"><img class="alignleft size-medium wp-image-455" src="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/parallel_program_design.jpg" alt="" width="240" height="240" align="left" /></a></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="small;"><span style="Times New Roman;"><span style="RU;">В</span> <span style="RU;">заголовок</span> <span style="RU;">этого</span> <span style="RU;">поста</span> <span style="RU;">вынесено</span> <span style="RU;">начало</span> <span style="RU;">эпиграфа</span> <span style="RU;">к</span> <span style="RU;">книге</span> <span lang="EN-US">K.Mani Chandy, Jayadev Misra “Parallel Program Design: A Foundation”</span><span lang="EN-US">. </span></span></span><span style="RU;"><span style="small;"><span style="Times New Roman;">Полностью этот эпиграф выглядит так:</span></span></span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span lang="EN-US"><span style="Times New Roman;">“The most general definition of beauty … Multeity in Unity”</span></span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span lang="EN-US"><span style="Times New Roman;">(Samuel Taylor Coleridge, “On the Principles of Genial Criticism”, 1814).</span></span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="small;"><span style="Times New Roman;"><span style="RU;">К чему это</span><span lang="EN-US">?</span></span></span></p>
<div></div>
<div><span style="small;"></span></div>
<div><span style="small;"><span style="Times New Roman;"></span></span></div>
<p><span style="small;"><span style="Times New Roman;"><span lang="EN-US"></p>
<p class="MsoNormal" style="justify;"><span style="RU;">Хотелось бы еще на одном примере показать, как грамотно выбранная система обозначений (читай, язык программирования) позволяет очень просто сформулировать алгоритм решения задачи, который в другой бы нотации записывался очень сложно, или, вообще бы казался нереализуемым.</span></p>
<p class="MsoNormal" style="justify;"><span style="RU;"> </span></p>
<p class="MsoNormal" style="justify;"><span style="RU;">Начнем чуть издалека. Многим хорошо известен язык логического программирования </span><span lang="EN-US">Prolog</span><span style="RU;">, программирование на котором в чистом виде состоит </span><span style="RU;">в том, что мы, в основном, выписываем правила того, ЧТО должно быть сделано </span><span style="RU;">для решения задачи, оставляя вопрос КАК это делать интерпретатору этого языка. </span><span style="RU;">Т.е., интерпретатор языка </span><span lang="EN-US">Prolog</span><span style="RU;" lang="EN-US"> </span><span style="RU;">выполняет любую программу единым образом – </span><span style="RU;">пытается сделать истинными предложения, из которых составлена программа, </span><span style="RU;">используя, возможно, откаты назад (так называемый бектрекинг).</span><span style="RU;"> </span></p>
<p class="MsoNormal" style="justify;"><span style="RU;">Существует довольно широкий класс задач, которые также можно решать некоторым единым способом. Это класс задач для которых решение находится </span><span style="RU;">с помощью итерационного процесса, который останавливается когда система перешла в некоторое стабильное состояние, или достигла, как говорят, некоторой неподвижной точки.</span><span style="RU;"> </span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="RU;">В упомянутой выше книге, излагается формализм для представления (программирования) такого рода задач – введена программная нотация и разработаны теоретические методы рассуждений (логика) о программах, записанных в данной нотации. Весь этот подход получил название </span><span lang="EN-US"><a href="http://www.cs.utexas.edu/users/psp/#unitysec">Unity</a></span><span style="RU;">. Следует заметить, что указанная книга и сопутствующие статьи составляют один из краеугольных камней науки </span><span style="RU;">о параллельном программировании, наряду с работами Хоара, Дейкстры и Милнера.</span><span style="RU;"> </span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="RU;">Язык программирования </span><span lang="EN-US">Unity</span><span style="RU;" lang="EN-US"> </span><span style="RU;">понять очень легко – мы его продемонстрируем </span><span style="RU;">на примере записи программы нахождения наибольшего общего делителя двух целых чисел:</span><span style="RU;"> </span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><strong><span lang="EN-US">Program </span></strong><span lang="EN-US">gcd</span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span lang="EN-US"><span style="1;">            </span><strong>declare </strong>x, y : integer</span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span lang="EN-US"><span style="1;">            </span><strong>initially </strong>x, y = X, Y</span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span lang="EN-US"><span style="1;">            </span><strong>assign</strong></span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><strong><span lang="EN-US"><span style="2;">                        </span></span></strong><span lang="EN-US">x, y := x – y, y<span style="yes;">  </span>if x &gt; y</span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span lang="EN-US"><span style="1;">            </span></span><span style="FR;" lang="FR"><span style="yes;">          </span>| x, y := x, y – x<span style="yes;">  </span>if y &gt; x</span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><strong><span lang="EN-US">e</span></strong><strong><span style="FR;" lang="FR">nd </span></strong><span style="FR;" lang="FR">{ gcd }</span><span style="FR;" lang="FR"> </span></p>
<p class="MsoNormal" style="justify;"><span style="RU;">Выполняется программа такого вида следующим образом: выбирается <span style="yes;"> </span>и вычисляется одно из присваиваний, для которого истинно условие выполнения. Если таких присваиваний несколько, то (недетерминированно) выбирается для исполнения только одно из них. Если таких присваиваний нет, то программа останавливается. Такого рода итерации продолжаются до тех пор, пока не наступит стабильное состояние – значения переменных на очередной итерации совпадут с предыдущими их значениями. (Более практические вопросы – ввод/вывод, модуляризация, и т.д. здесь, в иллюстративных целях, опущены). Заметим также, </span><span style="RU;">что данная нотация является внутренне параллельной – <span style="yes;"> </span>вычисление выражений, разделенных запятыми, в правой части присваиваний может выполняться одновременно. В частности, в указанной выше книге имеется несколько разделов, посвященных реализации этой модели вычислений на различных параллельных архитектурах – системах с передачей сообщений, систолических массивах, и т.п.</span><span style="RU;"> </span></p>
<p class="MsoNormal" style="justify;"><span style="RU;">Теперь реализуем с помощью </span><span lang="EN-US">Unity</span><span style="RU;"> модель некоторой системы, которая обсуждалась в комментариях к моим двум предыдущим постам. А именно, требуется реализовать в виде двух параллельных процессов модели логических элементов И-НЕ, связанных между собой перекрестными связями. А именно, </span><span style="RU;">выход </span><span lang="EN-US">y</span><span style="RU;">1 первого элемента вычисляется как</span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span lang="EN-US">y1 =<span style="yes;">  </span>NOT<span style="yes;">  </span>( x1<span style="yes;">  </span>AND y2 ),</span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="RU;">а выход </span><span lang="EN-US">y</span><span style="RU;">2 второго элемента вычисляется как</span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span lang="EN-US">y</span><span style="RU;">2 = </span><span lang="EN-US">NOT</span><span style="RU;"> ( </span><span lang="EN-US">x</span><span style="RU;">2 </span><span lang="EN-US">AND</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">y</span><span style="RU;">1 ).</span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="RU;">Как работает данная система – было проанализировано “на бумажке” </span><span style="RU;">в комментариях к предыдущим постам. Чтобы получить аналогичное поведение, </span><span style="RU;">мы просто напросто переносим определение системы в формализм </span><span lang="EN-US">Unity</span><span style="RU;">:</span><span style="RU;"> </span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><strong><span lang="EN-US">Program </span></strong><span lang="EN-US">Model</span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span lang="EN-US"><span style="1;">            </span><strong>declare </strong>x1, x2, y1, y2 : integer</span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span lang="EN-US"><span style="1;">            </span></span><strong><span style="FR;" lang="FR">initially </span></strong><span style="FR;" lang="FR">x1, x2, y1, y2 = 0, 0, 0, 0</span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="FR;" lang="FR"><span style="1;">            </span><strong>assign</strong></span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><strong><span style="FR;" lang="FR"><span style="1;">            </span><span style="1;">            </span></span></strong><span style="FR;" lang="FR">y1, y2 = </span><span style="RU;">1-</span><span style="FR;" lang="FR"> ( x1 &amp; y2 ), </span><span style="RU;">1 -</span><span style="FR;" lang="FR"> ( x2 &amp; y1 )<span style="1;">           </span><span style="yes;">   </span><span style="yes;">       </span></span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><strong><span style="FR;" lang="FR">end </span></strong><span style="FR;" lang="FR">{ </span><span lang="EN-US">Model</span><span style="FR;" lang="FR"> }</span><span style="FR;" lang="FR"> </span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="RU;">Программа (причем, параллельная) получена!</span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="RU;">И как вам это</span><span lang="EN-US">?</span><span style="RU;"> </span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span lang="EN-US">PS</span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="RU;">Всех с наступающим Новым годом ! </span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="RU;">И в качестве альбома для прослушивания на Новый год рекомендую </span></p>
<p class="MsoNormal" style="0cm 0cm 0pt;"><span style="RU;">один из лучших дисков 2007 года – </span><span lang="EN-US">Burial</span><span style="RU;"> “</span><span lang="EN-US"><a href="http://en.wikipedia.org/wiki/Untrue">Untrue</a></span><span style="RU;">” </span></p>
<p class="MsoNormal" style="justify;"> </p>
<div></div>
<p></span></span><span style="small;"></p>
<p class="MsoNormal" style="justify;"> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p> </p>
<p></span></span></p>
<p class="MsoNormal" style="justify;"> </p>
<p class="MsoNormal" style="0cm 0cm 0pt;"> </p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/ru-ru/blogs/2008/12/23/2-the-most-general-definition-of-beauty/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Многоядерность: 1,2,3, ... Larrabee, или как нам всё это программировать ?</title>
		<link>http://software.intel.com/ru-ru/blogs/2008/12/12/123-larrabee/</link>
		<comments>http://software.intel.com/ru-ru/blogs/2008/12/12/123-larrabee/#comments</comments>
		<pubDate>Fri, 12 Dec 2008 12:00:50 +0000</pubDate>
		<dc:creator>yuryserdyuk</dc:creator>
				<category><![CDATA[Intel Software Network]]></category>
		<category><![CDATA[Параллельное программирование]]></category>
		<category><![CDATA[Разработка софта]]></category>
		<category><![CDATA[C#]]></category>
		<category><![CDATA[HPC]]></category>
		<category><![CDATA[Larrabee]]></category>
		<category><![CDATA[LINQ]]></category>
		<category><![CDATA[mono]]></category>
		<category><![CDATA[TPL]]></category>
		<category><![CDATA[суперкомпьютер]]></category>

		<guid isPermaLink="false">http://software.intel.com/ru-ru/blogs/2008/12/12/123-larrabee/</guid>
		<description><![CDATA[Вы уже имеете 2-х ядерную машину? Наверняка, это так. И насколько оба ядра оказываются загруженными при запуске типичных приложений? А, может быть, у вас есть доступ к 4-х ядерной машине или даже к 8-ми ядерной? А как насчет попользоваться, а лучше, загрузить по полной процессор Larrabee ? (Кто вдруг не знает, что это такое, может посмотреть [...]]]></description>
			<content:encoded><![CDATA[<p><span style="AR-SA;">Вы уже имеете 2-х ядерную машину? Наверняка, это так. И насколько оба ядра оказываются загруженными при запуске типичных приложений? А, может быть, у вас есть доступ к 4-х ядерной машине или даже к 8-ми ядерной? <a href="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/larrabee_3.jpg"><img class="alignleft size-medium wp-image-406" style="margin: 4px;" src="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/larrabee_3.jpg" alt="" width="144" height="116" align="left" /></a><span style="RU;">А </span><span style="RU;">как насчет попользоваться, а лучше, загрузить по полной процессор </span><span lang="EN-US">Larrabee</span><span style="RU;"> ? (Кто вдруг не знает, что это такое, может посмотреть некоторое обсуждение <a href="http://ru.intel.com/business/community/?showtopic=124"><span style="#800080;">здесь</span></a>.) А вы задумывались по-настоящему о том, как такие машины программировать, чтобы, с одной стороны, действительно получить прирост производительности, соответствующий имеющимся ресурсам (т.е., количеству ядер), а с другой стороны, не снизить, как сейчас говорят, <em>продуктивность </em>в программировании, т.е., возможность писать <span style="yes;"> </span>примерно такое же количество отлаженных строк кода за единицу времени, что и раньше ?</span></span></p>
<p><span style="small;"><span style="Times New Roman;"><span style="RU;">Замечу, что под термином <em>“высокоуровневое программирование”</em> я понимаю не программирование на языке </span><span lang="EN-US">C</span><span style="RU;">++ (в отличие, допустим, от “низкоуровневого” программирования на языке С), а программирование, главным образом, на байт-кодовых языках (</span><span lang="EN-US">managed</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">languages</span><span style="RU;">), а среди них, в первую очередь, на языке </span><span lang="EN-US">C</span><span style="RU;">#. Причем я не буду сильно бороться против тезиса, что байт-кодовые языки непригодны или, даже более того, несовместимы с </span><span lang="EN-US">HPC</span><span style="RU;"> (</span><span lang="EN-US">high</span><span style="RU;">-</span><span lang="EN-US">performance</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">computations</span><span style="RU;">). В этом отношении, мой взгляд двоякий: во-первых, мы имеем в качестве данной такую ситуацию – имеются многоядерные машины (которые теперь уже, повторюсь, есть практически у всех ), и необходимо (опять же, уже каждому разработчику, если он хочет, чтобы его приложение выполнялось эффективно и конкурировало с аналогичными разработками) писать для них параллельные программы. Не забудем также тот аспект, что и программированию студентов нужно учить теперь тоже параллельному, причем, как можно раньше, на 1-2-х курсах. </span></span></span></p>
<p><span style="small;"><span style="Times New Roman;"><span style="RU;">Во-вторых, шансы побороться с утверждением, что </span><span lang="EN-US">managed</span><span style="RU;">-языки неприменимы для </span><span lang="EN-US">HPC</span><span style="RU;">, все-таки есть. Конечно, чтобы выжать максимальную производительность из приложения часто даже применения языка С недостаточно, и в этом случае переходят на ассемблерные вставки в код. (Показательным примером здесь является, скажем, программа перемножения матриц, ориентированная на процессор </span><span lang="EN-US">Cell</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">Broadband</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">Engine</span><span style="RU;">, с которой можно ознакомиться <a href="http://tu-dresden.de/die_tu_dresden/zentrale_einrichtungen/zih/forschung/architektur_und_leistungsanalyse_von_hochleistungsrechnern/cell/matmul/index_html/document_view?body_language=en"><span style="#800080;">здесь</span></a>.) С другой стороны, взгляните на такие оценки, очень близкие к реальным: 2-х дневный прогноз погоды по Европейской части России считается на кластере с достаточным количеством процессоров 1,5 – 2 мин., где само приложение написано на </span><span lang="EN-US">C</span><span style="RU;"> + </span><span lang="EN-US">MPI</span><span style="RU;"> + </span><span lang="EN-US">OpenMP</span><span style="RU;" lang="EN-US"> </span><span style="RU;">(аналогичные результаты по времени получаются и для связки </span><span lang="EN-US">Fortran</span><span style="RU;"> + </span><span lang="EN-US">MPI</span><span style="RU;"> + </span><span lang="EN-US">OpenMP</span><span style="RU;">). Допустим, что мы это приложение переписали (или написали заново) на языке </span><span lang="EN-US">C</span><span style="RU;"># с соответствующими средствами параллелизации. Если предположить, что в последнем случае производительность приложения будет в 1,5 – 2,5 раза ниже по сравнению с первым вариантом, то, тем не менее, мы тот же 2-х дневный прогноз погоды сможем получать на тех же вычислительных ресурсах за 3 – 5 мин. </span></span></span></p>
<p><span style="small;"><span style="Times New Roman;"><span style="RU;">С другой стороны, существуют объективные данные, что продуктивность работы программистов на высокоуровневых языках при разработке промышленных (в том числе, параллельных и распределенных) приложений в 2-10 раз выше, чем при использовании языков уровня </span><span lang="EN-US">C</span><span style="RU;">++. В применении к нашему примеру, это будет означать, что если на разработку параллельного варианта прогнозного приложения на языке </span><span lang="EN-US">C</span><span style="RU;"> (или </span><span lang="EN-US">Fortran</span><span style="RU;">) понадобится 6 месяцев, то на </span><span lang="EN-US">C</span><span style="RU;"># такой вариант будет разработан, отлажен и запущен в промышленную эксплуатацию приблизительно за 1 месяц. Понятно, что здесь кроется довольно существенная экономия реальных денег. Не забудем также про то, что такого рода приложения постоянно модифицируются и дорабатываются – понятно, что на высокоуровневых языках такая процедура будет проходить значительно быстрее, качественнее, а значит, в конечном итоге, и дешевле.</span></span></span></p>
<p class="MsoNormal" style="justify;"><span style="RU;">Вообщем, цель этого блога – освещение возможностей <em>высокоуровневого параллельного программирования </em>для современных компьютеров, и мой сегодняшний пост является введением в эту проблематику с кратким перечислением всего того, что будет в нем рассмотрено в дальнейшем.</span> </p>
<p class="MsoNormal" style="justify;"><span style="small;"><span style="Times New Roman;"><span style="RU;"><span style="AR-SA;">Язык </span><span style="AR-SA;" lang="EN-US">C</span><span style="AR-SA;">#, фактически, неотделим от платформы .</span><span style="AR-SA;" lang="EN-US">NET</span><span style="AR-SA;">, и в ближайших постах мы с нее<span style="yes;">  </span>и начнем рассмотрение вопросов программирования на параллельных </span><span style="AR-SA;" lang="EN-US">managed</span><span style="AR-SA;">-языках. Здесь только отмечу, что платформа .</span><span style="AR-SA;" lang="EN-US">NET</span><span style="AR-SA;" lang="EN-US"> <a href="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/mono-gorilla-aqua_100px1.png"><img class="alignleft size-medium wp-image-411" style="margin: 4px;" src="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/mono-gorilla-aqua_100px1.png" alt="" width="100" height="120" align="left" /></a><span style="small;"><span style="Times New Roman;"><span lang="EN-US">Framework</span><span style="RU;">, изначально являвшаяся разработкой фирмы </span><span lang="EN-US">Microsoft</span><span style="RU;">, еще шире пошла в программистские массы с появлением системы </span><span lang="EN-US">Mono</span><span style="RU;"> (</span><span lang="EN-US"><a href="http://www.mono-project.com/">www<span style="RU;" lang="RU">.</span>mono<span style="RU;" lang="RU">-</span>project<span style="RU;" lang="RU">.</span>com</a></span><span style="RU;"> ) – свободной реализации .</span><span lang="EN-US">NET</span><span style="RU;" lang="EN-US"> </span><span style="RU;">для </span><span lang="EN-US">Unix</span><span style="RU;">-подобных систем. В этом направлении дело дошло до того, что </span><span lang="EN-US">Mono</span><span style="RU;"> (.</span><span lang="EN-US">NET</span><span style="RU;">) уже работает на игровых приставках </span><span lang="EN-US">PlayStation</span><span style="RU;"> 3 и даже на </span><span lang="EN-US">iPhone</span><span style="RU;">! Сам язык </span><span lang="EN-US">C</span><span style="RU;"># также бурно развивается. Еще недавно мы обсуждали и продолжаем осваивать средства </span><span lang="EN-US">C</span><span style="RU;"># 2.0, а теперь средствами регулярного программирования становятся </span><span lang="EN-US">C</span><span style="RU;"># 3.0 и на подходе его следующая версия </span><span lang="EN-US"><a href="http://code.msdn.microsoft.com/csharpfuture"><span style="#800080;">C<span style="RU;" lang="RU"># 4.0</span></span></a></span><span style="RU;">.</span></span></span></span></span></span></span></p>
<p> </p>
<p><span style="small;"><span style="Times New Roman;"><span style="RU;"><span style="AR-SA;"><span style="small;"><span style="Times New Roman;"><span style="RU;">Язык </span><span lang="EN-US">C</span><span style="RU;"># со всевозможными расширениями на основе библиотек типа </span><span lang="EN-US">Parallel</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">FX</span><span style="RU;" lang="EN-US"> </span><span style="RU;">– это, можно сказать, <em>инженерный </em>подход к решению проблемы параллелизма. Существует, естественно, и <em>научный</em> подход к этой проблеме, суть которого состоит в разработке нового языка для параллельного программирования – недаром по научным конференциям соответствующей тематики кочует слоган “</span><span lang="EN-US">It</span><span style="RU;">’</span><span lang="EN-US">s</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">time</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">for</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">a</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">new</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">language</span><span style="RU;">”. И тотальный переход в “параллельный мир” к этому действительно побуждает. Ученые, в свою очередь, не остаются в долгу – упомянем, например, </span><span lang="EN-US"><a href="http://upc.gwu.edu/">UPC</a></span><span style="RU;">, </span><span lang="EN-US"><a href="http://research.microsoft.com/~nick/polyphony/">Polyhonic<span style="RU;"> </span>C<span style="RU;" lang="RU">#</span></a></span><span style="RU;">, </span><span lang="EN-US"><a href="http://www.mcsharp.net/"><span style="#800080;">MC<span style="RU;" lang="RU">#</span></span></a></span><span style="RU;">, </span><span lang="EN-US"><a href="http://x10-lang.org/"><span style="#800080;">X<span style="RU;" lang="RU">10</span></span></a></span><span style="RU;">, </span><span lang="EN-US"><a href="http://www.cilk.com/"><span style="#800080;">Cilk<span style="RU;" lang="RU">++</span></span></a></span><span style="RU;">, </span><span lang="EN-US"><a href="http://chapel.cs.washington.edu/">Chapel</a></span><span style="RU;">, </span><span lang="EN-US"><a href="http://techresearch.intel.com/articles/Tera-Scale/1514.htm"><span style="#800080;">Ct</span></a></span><span style="RU;" lang="EN-US"> </span><span style="RU;">и др. Хотя область языков программирования, по моему мнению, является довольно консервативной - <span style="yes;"> </span>новые, по настоящему ценные,<span style="yes;">  </span>модели программирования и соответствующие языковые средства появляются довольно редко, но в этих языках постепенно прорезываются новые интересные конструкции, которые станут базовыми средствами параллельных языков будущего. Все эти языки и некоторые другие будут обозреваться в наших постах, а то как эти языки соревнуются между собой в области </span><span lang="EN-US">HPC</span><span style="RU;">, можно найти на сайте </span><span lang="EN-US"><a href="http://www.hpcchallenge.org/"></a><a href="http://www.hpcchallenge.org.">www<span style="RU;" lang="RU">.</span>hpcchallenge<span style="RU;" lang="RU">.</span>org</a></span><span style="RU;">.</span></span></span></span></span></span></span></p>
<p class="MsoNormal" style="justify;"><span style="small;"><span style="Times New Roman;"><span style="RU;">Еще одной темой наших обсуждений, когда мы говорим о программировании многоядерных процессоров, конечно же, станет библиотека </span><span lang="EN-US">Parallel</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">FX</span><span style="RU;" lang="EN-US"> </span><span style="RU;">от </span><span lang="EN-US">Microsoft</span><span style="RU;">, состоящая из </span><span lang="EN-US"><a href="http://en.wikipedia.org/wiki/Task_Parallel_Library">Task<span style="RU;"> </span>Parallel<span style="RU;"> </span>Library<span style="RU;" lang="RU"> (</span>TPL<span style="RU;" lang="RU">)</span></a></span><span style="RU;" lang="EN-US"> </span><span style="RU;">и </span><span lang="EN-US"><a href="http://msdn.microsoft.com/en-us/magazine/cc163329.aspx">Parallel<span style="RU;"> </span>LINQ<span style="RU;" lang="RU"> (</span>PLINQ<span style="RU;" lang="RU">)</span></a></span><span style="RU;">. У </span><span lang="EN-US">Microsoft</span><span style="RU;" lang="EN-US"> </span><span style="RU;">есть превосходный ресурс по этой тематике - <a href="http://msdn.microsoft.com/en-us/concurrency/default.aspx"><span style="#800080;">http://msdn.microsoft.com/en-us/concurrency/default.aspx</span></a>, который содержит множество отличного материала, к которому мы будем часто обращаться и который будем обсуждать в этом блоге.<a href="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/hpc_server_2008.jpg"><img class="alignleft size-medium wp-image-413" style="margin: 4px;" src="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/hpc_server_2008.jpg" alt="" width="130" height="87" align="left" /></a> <span style="AR-SA;">Вообще, фирма </span><span style="AR-SA;" lang="EN-US">Microsoft</span><span style="AR-SA;"> (заметим, совместно с </span><span style="AR-SA;" lang="EN-US">Intel</span><span style="AR-SA;">) развила бурную деятельность в области параллельных вычислений, охватывающую весь спектр компьютеров – от многоядерных машин до мощнейших суперкомпьютеров (кстати, поинтересуйтесь на каком месте в </span><span style="AR-SA;" lang="EN-US">Top</span><span style="AR-SA;">500 – рейтинге пятисот самых мощных суперкомпьютеров в мире, находится машина, использующая новейший продукт от </span><span style="AR-SA;" lang="EN-US">Microsoft</span><span style="AR-SA;" lang="EN-US"> </span><span style="AR-SA;">– </span><span style="AR-SA;" lang="EN-US">Windows</span><span style="AR-SA;" lang="EN-US"> </span><span style="AR-SA;" lang="EN-US">HPC</span><span style="AR-SA;" lang="EN-US"> </span><span style="AR-SA;" lang="EN-US">Server</span><span style="AR-SA;"> 2008, и где эта машина конкретно установлена, и вы сильно удивитесь). </span></span></span></span>   </p>
<p class="MsoNormal" style="justify;"><span style="small;"><span style="Times New Roman;"><span style="RU;"><span style="RU;">В заключение, две загадки из довольно разных областей:</span><span style="RU;"> </span></span></span></span> </p>
<p class="MsoNormal" style="list 54.0pt;"><span style="RU;"><span style="Ignore;">1)<span style="7pt &quot;Times New Roman&quot;;">      </span></span></span><span style="RU;">язык </span><span lang="EN-US">Ct</span><span style="RU;" lang="EN-US"> </span><span style="RU;">основан на языке </span><span lang="EN-US">C</span><span style="RU;">, т.е., не является байт-ориентированным; тем не менее, для него существует </span><span lang="EN-US">JIT</span><span style="RU;">-компилятор; для чего он нужен и чем занимается этот компилятор ?</span></p>
<p class="MsoNormal" style="list 54.0pt;"><span style="RU;"><span style="Ignore;">2)<span style="7pt &quot;Times New Roman&quot;;">      </span></span></span><span style="RU;">НПО “Сатурн” (г. Рыбинск) в сентябре 2008 г. запустило <a href="http://www.pcweek.ru/themes/detail.php?ID=113407"><span style="#800080;">суперкомпьютер “<span style="EN-US;" lang="EN-US">A</span>Л-100”</span></a>; в ноябре это НПО обанкротилось и было национализировано (см. </span><span lang="EN-US"><a href="http://www.kommersant.ru/doc.aspx?DocsID=1088200"><span style="#800080;">“<span style="RU;" lang="RU">Коммерсант</span>”, 3 <span style="RU;" lang="RU">декабря 2008 г</span></span></a></span><span style="RU;">. )</span><span lang="EN-US">; </span><span style="RU;">что бы это значило </span><span lang="EN-US"> <img src='http://software.intel.com/ru-ru/blogs/wordpress/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  ?</span></p>
<p class="MsoNormal" style="list 54.0pt;"><span style="RU;">Свои ответы, а также любые предложения, замечания и комментарии оставляйте здесь. По-моему, у нас будет достаточно тем, которые надо обсудить …</span>                         </p>
<p class="MsoNormal" style="justify;"><span style="RU;"><span style="Times New Roman;">Ю.Сердюк  </span></span><span style="Times New Roman;"><span lang="EN-US">( info ( at ) mcsharp.net, <a href="http://www.mcsharp.net/"><span style="#800080;">www<span style="RU;" lang="RU">.</span>mcsharp<span style="RU;" lang="RU">.</span>net</span></a></span><span style="RU;"> ).</span></span></p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/ru-ru/blogs/2008/12/12/123-larrabee/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>Параллельное программирование - это просто ...</title>
		<link>http://software.intel.com/ru-ru/blogs/2008/12/10/389/</link>
		<comments>http://software.intel.com/ru-ru/blogs/2008/12/10/389/#comments</comments>
		<pubDate>Wed, 10 Dec 2008 13:32:50 +0000</pubDate>
		<dc:creator>yuryserdyuk</dc:creator>
				<category><![CDATA[Intel Software Network]]></category>
		<category><![CDATA[Параллельное программирование]]></category>
		<category><![CDATA[Разработка софта]]></category>
		<category><![CDATA[многопоточность]]></category>
		<category><![CDATA[многоядерность]]></category>
		<category><![CDATA[Параллельные вычисления]]></category>
		<category><![CDATA[языки программирования]]></category>

		<guid isPermaLink="false">http://software.intel.com/ru-ru/blogs/2008/12/10/389/</guid>
		<description><![CDATA[Добрый день!    Меня зовут Сердюк Юрий. Работаю в Институте программных систем Российской академии наук (ИПС РАН) в г. Переславле-Залесском. Занимаюсь параллельными вычислениями; конкретно, областью научных интересов являются языки для параллельного программирования и их формальные (математические) основы. С недавних пор (кстати, еще до начала многоядерной революции) появились идеи и желание сделать что-то практическое, т.е., то, чем реальным [...]]]></description>
			<content:encoded><![CDATA[<p class="MsoNormal" style="justify;"><span style="RU;"><span style="small;"><span style="Times New Roman;">Добрый день!</span></span></span><span style="RU;"><span style="Times New Roman;"> </span></span></p>
<p class="MsoNormal" style="justify;"><span style="small;"><span style="Times New Roman;"><a href="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/ips-l.gif"><img class="size-medium wp-image-390 alignleft" style="margin: 4px;" src="http://software.intel.com/ru-ru/blogs/wordpress/wp-content/uploads/ips-l.gif" alt="" width="73" height="73" align="left" /></a></span></span></p>
<p class="MsoNormal" style="justify;">
<div></div>
<div><span style="small;"></span></div>
<p><span style="small;"><span style="Times New Roman;"></p>
<p class="MsoNormal" style="justify;"><span style="RU;">  <span style="RU;">Меня зовут Сердюк Юрий. Работаю в Институте программных систем Российской академии наук (ИПС РАН) в г. Переславле-Залесском. Занимаюсь параллельными вычислениями; конкретно, областью научных интересов являются языки для параллельного программирования и их формальные (математические) основы. С недавних пор (кстати, еще до начала многоядерной революции) появились идеи и желание сделать что-то практическое, т.е., то, чем реальным разработчикам захотелось бы пользоваться ежедневно в своей работе. Часть материалов нашего проекта </span><span lang="EN-US">MC</span><span style="RU;"># представлена <a href="http://www.mcsharp.net/"><span style="#800080;">здесь</span></a>.</span></span></p>
<p></span></span></p>
<p><span style="RU;"><span style="small;"><span style="Times New Roman;"><span style="small;"><span style="Times New Roman;"><span style="RU;">С удовольствием принял приглашение от </span><span lang="EN-US">Intel</span><span style="RU;" lang="EN-US"> </span><span style="RU;">освещать тему высокопроизводительных (читай, многоядерных, многопоточных и т.п.) вычислений на языках высокого уровня (</span><span lang="EN-US">managed</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">languages</span><span style="RU;">) в рамках российской части </span><span lang="EN-US">Intel</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">Software</span><span style="RU;" lang="EN-US"> </span><span lang="EN-US">Network</span><span style="RU;">. С одной стороны, хочется поделиться собственными мыслями – а соответствующих тем имеется великое множество, а с другой стороны, интересно узнать что думает на эту тему программистское сообщество, и насколько внутри него есть потребность в упомянутых инструментах. Наконец, хотелось бы просто привлечь к этой тематике побольше народу, поскольку она является, по моему мнению, достаточно перспективной.</span></span></span><span style="RU;"><span style="Times New Roman;"> </span></span></p>
<p></span></span></span></p>
<p class="MsoNormal" style="justify;"><span style="RU;"><span style="small;"><span style="Times New Roman;">Мне кажется, что сейчас в программировании наступает период, аналогичный тому, что был 50 лет назад, когда произошел переход от программирования на машинных (ассемблерных) языках к языкам программирования высокого уровня (Алгол, Фортран). Конечно, мы при этом несколько потеряли в эффективности исполнения программ, что стало платой за удобства программирования, но последнее, как мы сейчас видим, очевидно перевесило первое. </span></span></span><span style="RU;"><span style="Times New Roman;"> </span></span></p>
<p class="MsoNormal" style="justify;"><span style="small;"><span style="Times New Roman;"><span style="RU;">Сейчас базовыми средствами параллельного программирования являются </span><span lang="EN-US">C</span><span style="RU;">/</span><span lang="EN-US">C</span><span style="RU;">++, </span><span lang="EN-US">MPI</span><span style="RU;" lang="EN-US"> </span><span style="RU;">и </span><span lang="EN-US">OpenMP</span><span style="RU;">, которые относятся к низкоуровневым средствам, и программировать на которых трудно. Переход к более абстрактным, высокоуровневым инструментам не будет таким простым и безболезненным по целому ряду причин: одна из них – наличие огромного объема уже наработанного программного обеспечения. Появится ли реально что-то новое, более высокоуровневое и достаточно эффективное – см. об этом в следующих постах данного блога.</span></span></span><span style="RU;"><span style="Times New Roman;"> </span></span></p>
<p class="MsoNormal"><span style="small;"><span style="Times New Roman;"><span style="RU;">Комментарии можно оставлять здесь или отправлять непосредственно мне на </span><span lang="EN-US">info</span><span style="RU;"> (</span><span lang="EN-US">at</span><span style="RU;">) </span><span lang="EN-US">mcsharp</span><span style="RU;">.</span><span lang="EN-US">net</span><span style="RU;">.</span></span></span></p>
]]></content:encoded>
			<wfw:commentRss>http://software.intel.com/ru-ru/blogs/2008/12/10/389/feed/</wfw:commentRss>
		<slash:comments>53</slash:comments>
		</item>
	</channel>
</rss>

