<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Diana+Pimenova</id>
	<title>Алговики - Вклад [ru]</title>
	<link rel="self" type="application/atom+xml" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Diana+Pimenova"/>
	<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/ru/%D0%A1%D0%BB%D1%83%D0%B6%D0%B5%D0%B1%D0%BD%D0%B0%D1%8F:%D0%92%D0%BA%D0%BB%D0%B0%D0%B4/Diana_Pimenova"/>
	<updated>2026-10-22T17:09:17Z</updated>
	<subtitle>Вклад</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=24264</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=24264"/>
		<updated>2017-11-26T15:58:01Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i (i = 0, …, q)&amp;lt;/math&amp;gt; блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; одного из процессов пересылается во все процессы этой же строки.&lt;br /&gt;
* Полученный в результате подобной пересылки блок матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и содержащийся в процессе &amp;lt;math&amp;gt;(i, j)&amp;lt;/math&amp;gt;&lt;br /&gt;
блок матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; перемножаются, и результат прибавляется к матрице &amp;lt;math&amp;gt;С_{ij}&amp;lt;/math&amp;gt;.&lt;br /&gt;
* Для каждого столбца &amp;lt;math&amp;gt;j (j = 0, …, q)&amp;lt;/math&amp;gt; выполняется циклическая пересылка блоков матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;, содер-&lt;br /&gt;
жащихся в каждом процессе &amp;lt;math&amp;gt;(i, j)&amp;lt;/math&amp;gt; этого столбца, в направлении убывания номеров строк.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Число блоков определяется как округление снизу корня квадратного из числа доступных процессов.&lt;br /&gt;
[[File: fox.jpg|thumb|center|400px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Синим цветом на информационном графе отмечен этап инициализации результирующей матрицы, то есть заполнение всех блоков нулями. Красным цветом обозначен этап, на котором происходит умножение подматриц, хранящихся в этом процессе, а также обмен подматрицами с другими процессами и прибавление произведения переданных подматриц на сохраненные(на картинках в начале статьи более подробно нарисовано, какие блоки передаются).Желтым цветом обозначен уже вывод результата соответствующего блока.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
== Локальность данных и вычислений ===&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox1.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox2.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
[[File: Fox3.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6. Использованная реализация MPI: Intel MPI 4.0.3. Опции компилятора: -lm.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на некоторые существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
[http://www.opennet.ru/docs/RUS/linux_parallel/node164.html] - OpenNET&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=24262</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=24262"/>
		<updated>2017-11-26T15:51:44Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
Число блоков определяется как округление снизу корня квадратного из числа доступных процессов.&lt;br /&gt;
[[File: fox.jpg|thumb|center|400px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Синим цветом на информационном графе отмечен этап инициализации результирующей матрицы, то есть заполнение всех блоков нулями. Красным цветом обозначен этап, на котором происходит умножение подматриц, хранящихся в этом процессе, а также обмен подматрицами с другими процессами и прибавление произведения переданных подматриц на сохраненные(на картинках в начале статьи более подробно нарисовано, какие блоки передаются).Желтым цветом обозначен уже вывод результата соответствующего блока.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
== Локальность данных и вычислений ===&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox1.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox2.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
[[File: Fox3.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6. Использованная реализация MPI: Intel MPI 4.0.3. Опции компилятора: -lm.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на некоторые существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
[http://www.opennet.ru/docs/RUS/linux_parallel/node164.html] - OpenNET&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23996</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23996"/>
		<updated>2017-11-16T20:08:36Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
Число блоков определяется как округление снизу корня квадратного из числа доступных процессов.&lt;br /&gt;
[[File: Foxgraph.png|thumb|center|400px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Синим цветом на информационном графе отмечен этап инициализации результирующей матрицы, то есть заполнение всех блоков нулями. Красным цветом обозначен этап, на котором происходит умножение подматриц, хранящихся в этом процессе, а также обмен подматрицами с другими процессами и прибавление произведения переданных подматриц на сохраненные(на картинках в начале статьи более подробно нарисовано, какие блоки передаются).Желтым цветом обозначен уже вывод результата соответствующего блока.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
== Локальность данных и вычислений ===&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox1.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox2.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
[[File: Fox3.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6. Использованная реализация MPI: Intel MPI 4.0.3. Опции компилятора: -lm.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на некоторые существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
[http://www.opennet.ru/docs/RUS/linux_parallel/node164.html] - OpenNET&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23995</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23995"/>
		<updated>2017-11-16T20:05:16Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
Число блоков определяется как округление снизу корня квадратного из числа доступных процессов.&lt;br /&gt;
[[File: Foxgraph.png|thumb|center|400px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Синим цветом на информационном графе отмечен этап инициализации результирующей матрицы, то есть заполнение всех блоков нулями. Красным цветом обозначен этап, на котором происходит умножение подматриц, хранящихся в этом процессе, а также обмен подматрицами с другими процессами и прибавление произведения переданных подматриц на сохраненные.Желтым цветом обозначен уже вывод результата соответствующего блока.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
== Локальность данных и вычислений ===&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox1.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox2.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
[[File: Fox3.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6. Использованная реализация MPI: Intel MPI 4.0.3. Опции компилятора: -lm.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на некоторые существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
[http://www.opennet.ru/docs/RUS/linux_parallel/node164.html] - OpenNET&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23994</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23994"/>
		<updated>2017-11-16T20:04:18Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
[[File: Foxgraph.png|thumb|center|400px|]]&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Синим цветом на информационном графе отмечен этап инициализации результирующей матрицы, то есть заполнение всех блоков нулями. Красным цветом обозначен этап, на котором происходит умножение подматриц, хранящихся в этом процессе, а также обмен подматрицами с другими процессами и прибавление произведения переданных подматриц на сохраненные.Желтым цветом обозначен уже вывод результата соответствующего блока.&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
== Локальность данных и вычислений ===&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox1.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox2.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
[[File: Fox3.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6. Использованная реализация MPI: Intel MPI 4.0.3. Опции компилятора: -lm.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на некоторые существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
[http://www.opennet.ru/docs/RUS/linux_parallel/node164.html] - OpenNET&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23987</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23987"/>
		<updated>2017-11-16T19:48:30Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
[[File: Foxgraph.png|thumb|center|400px|]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
== Локальность данных и вычислений ===&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox1.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox2.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
[[File: Fox3.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6. Использованная реализация MPI: Intel MPI 4.0.3. Опции компилятора: -lm.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на некоторые существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
[http://www.opennet.ru/docs/RUS/linux_parallel/node164.html] - OpenNET&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23986</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23986"/>
		<updated>2017-11-16T19:48:16Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
[[File: Foxgraph.png|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
== Локальность данных и вычислений ===&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox1.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox2.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
[[File: Fox3.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6. Использованная реализация MPI: Intel MPI 4.0.3. Опции компилятора: -lm.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на некоторые существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
[http://www.opennet.ru/docs/RUS/linux_parallel/node164.html] - OpenNET&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23985</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23985"/>
		<updated>2017-11-16T19:46:57Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png|thumb|center|500px|]]&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
== Локальность данных и вычислений ===&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox1.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox2.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
[[File: Fox3.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6. Использованная реализация MPI: Intel MPI 4.0.3. Опции компилятора: -lm.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на некоторые существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
[http://www.opennet.ru/docs/RUS/linux_parallel/node164.html] - OpenNET&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23984</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23984"/>
		<updated>2017-11-16T19:46:29Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
== Локальность данных и вычислений ===&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox1.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox2.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
[[File: Fox3.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6. Использованная реализация MPI: Intel MPI 4.0.3. Опции компилятора: -lm.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на некоторые существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
[http://www.opennet.ru/docs/RUS/linux_parallel/node164.html] - OpenNET&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23983</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23983"/>
		<updated>2017-11-16T19:28:27Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Характеристики программно-аппаратной среды */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
== Локальность данных и вычислений ===&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox1.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox2.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
[[File: Fox3.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6. Использованная реализация MPI: Intel MPI 4.0.3. Опции компилятора: -lm.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на некоторые существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
[http://www.opennet.ru/docs/RUS/linux_parallel/node164.html] - OpenNET&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23982</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23982"/>
		<updated>2017-11-16T19:22:26Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Масштабируемость алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
== Локальность данных и вычислений ===&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox1.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
[[File: Fox2.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
[[File: Fox3.jpg|thumb|center|600px|]]&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на некоторые существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
[http://www.opennet.ru/docs/RUS/linux_parallel/node164.html] - OpenNET&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23970</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23970"/>
		<updated>2017-11-16T06:17:41Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Свойства алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Особенности реализации последовательного алгоритма ===&lt;br /&gt;
== Локальность данных и вычислений ===&lt;br /&gt;
== Возможные способы и особенности параллельной реализации алгоритма ===&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Динамические характеристики и эффективность реализации алгоритма ==&lt;br /&gt;
== Выводы для классов архитектур ==&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на некоторые существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
[http://www.opennet.ru/docs/RUS/linux_parallel/node164.html] - OpenNET&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23965</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23965"/>
		<updated>2017-11-15T18:19:17Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на некоторые существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
[http://www.opennet.ru/docs/RUS/linux_parallel/node164.html] - OpenNET&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23964</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23964"/>
		<updated>2017-11-15T18:17:52Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на некоторые существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23963</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23963"/>
		<updated>2017-11-15T18:17:41Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23962</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23962"/>
		<updated>2017-11-15T18:17:24Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на существующие реализации этого алгоритма:&lt;br /&gt;
&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23961</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23961"/>
		<updated>2017-11-15T18:17:07Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Существующие реализации алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
Ссылки на существующие реализации этого алгоритма:&lt;br /&gt;
[http://www.hpcc.unn.ru/?dir=889] - центр суперкомпьютерных технологий Нижегородского Государственного Университета.&lt;br /&gt;
[http://www.intuit.ru/studies/courses/1156/190/lecture/4954?page=4] - ИНТУИТ&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23953</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23953"/>
		<updated>2017-11-14T22:07:10Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
[[File:Fox1.png]]&lt;br /&gt;
&lt;br /&gt;
[[File:Fox2.png]]&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23952</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23952"/>
		<updated>2017-11-14T21:58:39Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Масштабируемость алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Возьмем квадратные матрицы размерностью  &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant n \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов будем изменять от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. В качестве примера приведем время выполнения программы в зависимости от числа процессов при фиксированном размере матриц &amp;lt;math&amp;gt;n = 2000&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Далее рассмотрим зависимость времени выполнения программы от размера матриц. Число процессов также зафиксируем: возьмем &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt; процесса.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Из приведенных результатов исследования видно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23951</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23951"/>
		<updated>2017-11-14T21:53:33Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Масштабируемость алгоритма и его реализации */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
=== Масштабируемость алгоритма ===&lt;br /&gt;
&lt;br /&gt;
Рассматривались квадратные матрицы размерностью  &amp;lt;math&amp;gt;N&amp;lt;/math&amp;gt;, где  &amp;lt;math&amp;gt;500\leqslant N \leqslant 2000&amp;lt;/math&amp;gt;, а число процессов изменялось от  &amp;lt;math&amp;gt;2&amp;lt;/math&amp;gt; до &amp;lt;math&amp;gt;128&amp;lt;/math&amp;gt;. Для примера посмотрим как изменялось время выполнения программы в зависимости от числа процессов (здесь берутся матрицы размера &amp;lt;math&amp;gt;N = 2000&amp;lt;/math&amp;gt;)&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Число процессов&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|128&lt;br /&gt;
|0.510&lt;br /&gt;
|-&lt;br /&gt;
|64&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|32&lt;br /&gt;
|2.556&lt;br /&gt;
|-&lt;br /&gt;
|16&lt;br /&gt;
|5.121&lt;br /&gt;
|-&lt;br /&gt;
|8&lt;br /&gt;
|20.844&lt;br /&gt;
|-&lt;br /&gt;
|4&lt;br /&gt;
|20.952&lt;br /&gt;
|-&lt;br /&gt;
|2&lt;br /&gt;
|92.919&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
А теперь посмотрим на зависимость времени выполнения программы от размера матриц. Число процессов зафиксируем равным &amp;lt;math&amp;gt;64&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
{| class=&amp;quot;wikitable&amp;quot;&lt;br /&gt;
|-&lt;br /&gt;
! Размер матриц&lt;br /&gt;
! Время (с)&lt;br /&gt;
|-&lt;br /&gt;
|2000&lt;br /&gt;
|1.038&lt;br /&gt;
|-&lt;br /&gt;
|1500&lt;br /&gt;
|0.409&lt;br /&gt;
|-&lt;br /&gt;
|1000&lt;br /&gt;
|0.115&lt;br /&gt;
|-&lt;br /&gt;
|750&lt;br /&gt;
|0.049&lt;br /&gt;
|-&lt;br /&gt;
|500&lt;br /&gt;
|0.015&lt;br /&gt;
|-&lt;br /&gt;
|}&lt;br /&gt;
&lt;br /&gt;
Очевидно, что система хорошо масштабируема.&lt;br /&gt;
&lt;br /&gt;
=== Характеристики программно-аппаратной среды ===&lt;br /&gt;
&lt;br /&gt;
Все вычисления были произведены на суперкомпьютере &amp;quot;Ломоносов&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Для компиляции был использован компилятор языка C++ GNU 4.4.6.&lt;br /&gt;
&lt;br /&gt;
Вычисления производились в очереди test. Ограничений на лимит времени на узел наложено не было.&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23752</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23752"/>
		<updated>2017-11-04T10:07:51Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Входные и выходные данные алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Входные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;a_{ij}&amp;lt;/math&amp;gt;), матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;b_{ij}&amp;lt;/math&amp;gt;)).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём входных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;2n^{2}&amp;lt;/math&amp;gt; &lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Выходные данные&#039;&#039;&#039;: матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (элементы &amp;lt;math&amp;gt;c_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Объём выходных данных&#039;&#039;&#039;: &amp;lt;math&amp;gt;n^{2}&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23751</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23751"/>
		<updated>2017-11-04T10:07:00Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Ресурс параллелизма алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
Определим вычислительную сложность данного алгоритма. Пусть все матрицы являются квадратными размера &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, количество блоков по горизонтали и вертикали являются одинаковым и равным &amp;lt;math&amp;gt; q &amp;lt;/math&amp;gt;&amp;amp;nbsp; (т.е. размер всех блоков равен &amp;lt;math&amp;gt;k \times k&amp;lt;/math&amp;gt;&amp;amp;nbsp;, где &amp;lt;math&amp;gt;k = \frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;), процессоры образуют квадратную решетку и их количество равно &amp;lt;math&amp;gt;p = q^{2}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Алгоритм Фокса требует для своего выполнения &amp;lt;math&amp;gt;q&amp;lt;/math&amp;gt;&amp;amp;nbsp; итераций, в ходе которых каждый процессор перемножает свои текущие блоки матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt;&amp;amp;nbsp; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;&amp;amp;nbsp; и прибавляет результаты умножения к текущему значению блока матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;&amp;amp;nbsp;. С учетом выдвинутых предположений общее количество выполняемых при этом операций будет иметь порядок &amp;lt;math&amp;gt;\frac{n^{3}}{p}&amp;lt;/math&amp;gt;&amp;amp;nbsp;.&lt;br /&gt;
&lt;br /&gt;
Определим количество вычислительных операций. Сложность выполнения скалярного умножения строки блока матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на столбец блока матрицы  &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; можно оценить как&amp;lt;math&amp;gt;2\frac{n}{q} - 1&amp;lt;/math&amp;gt; . Количество строк и столбцов в блоках равно &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt; и, как результат, трудоемкость операции блочного умножения оказывается равной &amp;lt;math&amp;gt;\frac{\frac{n^2}{p}}{\frac{2n}{q} - 1}&amp;lt;/math&amp;gt;. Для сложения блоков требуется&amp;lt;math&amp;gt;\frac{n^{2}}{p}&amp;lt;/math&amp;gt;  операций.&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23750</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23750"/>
		<updated>2017-11-04T09:26:59Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Информационный граф */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
Сначала опишем идею параллельного умножения матриц методом Фокса:&lt;br /&gt;
&lt;br /&gt;
* Каждой подзадаче &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; передаются блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и обнуляются блоки &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; на всех подзадачах.&lt;br /&gt;
* Для каждой строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt;  блок &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt; подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылается на все подзадачи той же строки &amp;lt;math&amp;gt;i&amp;lt;/math&amp;gt; решетки.&lt;br /&gt;
* Полученные в результаты пересылок блоки &amp;lt;math&amp;gt;A&#039;_{ij}&amp;lt;/math&amp;gt;, &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; перемножаются и прибавляются к блоку &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;&amp;lt;math&amp;gt;: C_{ij} = C_{ij} + A&#039;_{ij}B&#039;_{ij} &amp;lt;/math&amp;gt;.&lt;br /&gt;
* блоки &amp;lt;math&amp;gt;B&#039;_{ij}&amp;lt;/math&amp;gt; каждой подзадачи &amp;lt;math&amp;gt;(i,j)&amp;lt;/math&amp;gt; пересылаются подзадачам, являющимися соседями сверху в столбцах решетки подзадач (блоки подзадач из первой строки решетки пересылаются подзадачам последней строки решетки).&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23749</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23749"/>
		<updated>2017-11-04T08:53:27Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Последовательная сложность алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Рассмотрим квадратные матрицы размером &amp;lt;math&amp;gt;n \times n&amp;lt;/math&amp;gt;&amp;amp;nbsp;, разбитые на  блоки размера &amp;lt;math&amp;gt;\frac{n}{q}&amp;lt;/math&amp;gt;&amp;amp;nbsp;. Итого у нас получается &amp;lt;math&amp;gt;q \times q&amp;lt;/math&amp;gt;&amp;amp;nbsp; блоков.&lt;br /&gt;
&lt;br /&gt;
Для умножение данных матриц в последовательном варианте требуется по &amp;lt;math&amp;gt; n^3 &amp;lt;/math&amp;gt;&amp;amp;nbsp; умножений и сложений.&lt;br /&gt;
&lt;br /&gt;
При классификации по последовательной сложности, таким образом, алгоритм умножения матриц относится к алгоритмам &#039;&#039;с кубической сложностью&#039;&#039;.&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23748</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23748"/>
		<updated>2017-11-04T08:40:56Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
== Масштабируемость алгоритма и его реализации ==&lt;br /&gt;
&lt;br /&gt;
== Существующие реализации алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23426</id>
		<title>Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23426"/>
		<updated>2017-10-23T19:29:18Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: Полностью удалено содержимое страницы&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova&amp;diff=23424</id>
		<title>Участник:Diana Pimenova</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova&amp;diff=23424"/>
		<updated>2017-10-23T19:29:04Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Пименова Диана Вячеславовна, студент 4 курса ВМК МГУ, кафедры системного анализа.&lt;br /&gt;
&lt;br /&gt;
[[Участник:Diana Pimenova/Алгоритм Фокса умножения матриц]]&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23423</id>
		<title>Участник:Diana Pimenova/Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova/%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23423"/>
		<updated>2017-10-23T19:28:52Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: Новая страница: «Автор:  Д.В.Пименова  = Свойства и структура алгоритмов =  == Общее описа…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova&amp;diff=23378</id>
		<title>Участник:Diana Pimenova</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:Diana_Pimenova&amp;diff=23378"/>
		<updated>2017-10-23T15:12:48Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: Новая страница: «Пименова Диана Вячеславовна, студент 4 курса ВМК МГУ, кафедры системного анализа.»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Пименова Диана Вячеславовна, студент 4 курса ВМК МГУ, кафедры системного анализа.&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23376</id>
		<title>Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=23376"/>
		<updated>2017-10-23T15:11:13Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Автор:  [[Участник:Diana Pimenova|Д.В.Пименова]]&lt;br /&gt;
&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22919</id>
		<title>Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22919"/>
		<updated>2017-10-09T17:44:12Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Вычислительное ядро алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&amp;lt;ref&amp;gt;http://it.kgsu.ru/ParalAlg/palg046.html&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22918</id>
		<title>Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22918"/>
		<updated>2017-10-09T17:43:06Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&amp;lt;ref&amp;gt;Лекции по высокопроизводительным вычислительным системам СПбГПУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22917</id>
		<title>Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22917"/>
		<updated>2017-10-09T17:39:16Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Литература */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22916</id>
		<title>Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22916"/>
		<updated>2017-10-09T17:39:02Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&amp;lt;ref&amp;gt;Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016.&amp;lt;/ref&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
1. Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016&lt;br /&gt;
&lt;br /&gt;
2. Гергель В. П. Теория и практика параллельных вычислений: учебное пособие, ИНТУИТ, 2007&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22915</id>
		<title>Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22915"/>
		<updated>2017-10-09T17:32:54Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти, что дает нам уменьшение времени работы программы.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
1. Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016&lt;br /&gt;
&lt;br /&gt;
2. Гергель В. П. Теория и практика параллельных вычислений: учебное пособие, ИНТУИТ, 2007&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22914</id>
		<title>Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22914"/>
		<updated>2017-10-09T17:31:08Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Общее описание алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход хранения позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти.&lt;br /&gt;
&lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
1. Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016&lt;br /&gt;
&lt;br /&gt;
2. Гергель В. П. Теория и практика параллельных вычислений: учебное пособие, ИНТУИТ, 2007&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22913</id>
		<title>Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22913"/>
		<updated>2017-10-09T17:16:32Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
С_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
1. Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016&lt;br /&gt;
&lt;br /&gt;
2. Гергель В. П. Теория и практика параллельных вычислений: учебное пособие, ИНТУИТ, 2007&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22912</id>
		<title>Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22912"/>
		<updated>2017-10-09T17:13:42Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: /* Схема реализации последовательного алгоритма */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
Разобьем исходные матрицы на блоки &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;,&amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; соответственно. &lt;br /&gt;
Обнулим блоки матрицы &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt;, предназначенной для хранения соответствующего результирующего произведения &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
Затем запускается цикл, в ходе которого выполняется последовательное умножение блоков матриц операндов и суммирование полученных результатов.&lt;br /&gt;
 &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
S_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
После завершения цикла мы получим матрицу с блоками &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;, соответствующую произведению &amp;lt;math&amp;gt;AB&amp;lt;/math&amp;gt;.&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
1. Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016&lt;br /&gt;
&lt;br /&gt;
2. Гергель В. П. Теория и практика параллельных вычислений: учебное пособие, ИНТУИТ, 2007&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22900</id>
		<title>Алгоритм Фокса умножения матриц</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=%D0%90%D0%BB%D0%B3%D0%BE%D1%80%D0%B8%D1%82%D0%BC_%D0%A4%D0%BE%D0%BA%D1%81%D0%B0_%D1%83%D0%BC%D0%BD%D0%BE%D0%B6%D0%B5%D0%BD%D0%B8%D1%8F_%D0%BC%D0%B0%D1%82%D1%80%D0%B8%D1%86&amp;diff=22900"/>
		<updated>2017-10-09T12:46:42Z</updated>

		<summary type="html">&lt;p&gt;Diana Pimenova: Новая страница: « = Свойства и структура алгоритмов = == Общее описание алгоритма == Метод Фокса - это блочны…»&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;&lt;br /&gt;
= Свойства и структура алгоритмов =&lt;br /&gt;
== Общее описание алгоритма ==&lt;br /&gt;
Метод Фокса - это блочный алгоритм умножения квадратных матриц. Основная его идея заключается в том, что матрицы разбиваются на части, представляющие собой подматрицы исходных матриц (разделяются как матрицы-операнды, так и результирующая). При таком разбиении данных для определения базовых подзадач за основу берутся вычисления, выполняемые над блоками. А базовой подзадачей является процедура вычисления всех элементов одного из блоков результирующей матрицы. В отличие от стандартного ленточного алгоритма, когда мы рассматриваем матрицы в виде набора строк и столбцов, такой подход позволяет добиться большей локализации данных и повысить эффективность использования кэш-памяти.&lt;br /&gt;
&lt;br /&gt;
 &lt;br /&gt;
== Математическое описание алгоритма ==&lt;br /&gt;
Исходные данные: квадратная матрица &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;A_{ij}&amp;lt;/math&amp;gt;), квадратная матрица &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;B_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
Вычисляемые данные: квадратная матрица &amp;lt;math&amp;gt;C&amp;lt;/math&amp;gt; (состоит из блоков &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt;).&lt;br /&gt;
&lt;br /&gt;
При этом каждый блок &amp;lt;math&amp;gt;C_{ij}&amp;lt;/math&amp;gt; определяется как произведение соответствующих блоков матриц &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; и &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; :&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
C_{ij} = \sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Вычислительное ядро алгоритма ==&lt;br /&gt;
Вычислительное ядро перемножения квадратных матриц методом Фокса можно составить из процедур вычисления всех элементов одного из блоков результирующей матрицы, т.е. из процедур множественных вычислений умножения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt; &lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{s = 0}^{q-1} A_{is} B_{sj}, \quad i \in [0, q-1],\quad j \in [0, q-1].&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
== Макроструктура алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Как уже записано в [[#Вычислительное ядро алгоритма|описании ядра алгоритма]], основную часть умножения матриц составляют множественные вычисления произведения блоков матрицы &amp;lt;math&amp;gt;A&amp;lt;/math&amp;gt; на блоки матрицы &amp;lt;math&amp;gt;B&amp;lt;/math&amp;gt;. Перемножать блоки будем стандартным методом, используя определение произведения матриц:&lt;br /&gt;
:&amp;lt;math&amp;gt;&lt;br /&gt;
\begin{align}&lt;br /&gt;
\sum_{k = 1}^{n} a_{ik} b_{kj}&lt;br /&gt;
\end{align}&lt;br /&gt;
&amp;lt;/math&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Схема реализации последовательного алгоритма ==&lt;br /&gt;
&lt;br /&gt;
Вначале производится рассылка в процесс с координатами (i, j) блоков Aij, Bij исходных матриц.&lt;br /&gt;
Кроме того, выполняется обнуление матрицы Cij, предназначенной для хранения соответствующего блока&lt;br /&gt;
результирующего произведения AB.&lt;br /&gt;
Затем запускается цикл по m (m = 0, …, q), в ходе которого выполняются три действия:&lt;br /&gt;
* для каждой строки i (i = 0, …, q) блок Aij одного из процессов пересылается во все процессы этой&lt;br /&gt;
же строки; при этом индекс j пересылаемого блока определяется по формуле j = (i + m) mod q;&lt;br /&gt;
* полученный в результате подобной пересылки блок матрицы A и содержащийся в процессе (i, j)&lt;br /&gt;
блок матрицы B перемножаются, и результат прибавляется к матрице Сij;&lt;br /&gt;
* для каждого столбца j (j = 0, …, q) выполняется циклическая пересылка блоков матрицы B, содержащихся в каждом процессе (i, j) этого столбца, в направлении убывания номеров строк.&lt;br /&gt;
&lt;br /&gt;
После завершения цикла в каждом процессе будет содержаться матрица Cij, равная соответствующему блоку произведения AB. Останется переслать эти блоки главному процессу.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
== Последовательная сложность алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Информационный граф ==&lt;br /&gt;
&lt;br /&gt;
== Ресурс параллелизма алгоритма ==&lt;br /&gt;
&lt;br /&gt;
== Входные и выходные данные алгоритма ==&lt;br /&gt;
&lt;br /&gt;
= Программная реализация алгоритма =&lt;br /&gt;
&lt;br /&gt;
= Литература =&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;br /&gt;
1. Абрамян М.Э. Лекции по основам параллельного программирования, ЮФУ, 2016&lt;br /&gt;
&lt;br /&gt;
2. Гергель В. П. Теория и практика параллельных вычислений: учебное пособие, ИНТУИТ, 2007&lt;/div&gt;</summary>
		<author><name>Diana Pimenova</name></author>
	</entry>
</feed>