<?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/index.php?action=history&amp;feed=atom&amp;title=Thomas_algorithm%2C_locality</id>
	<title>Thomas algorithm, locality - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?action=history&amp;feed=atom&amp;title=Thomas_algorithm%2C_locality"/>
	<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=Thomas_algorithm,_locality&amp;action=history"/>
	<updated>2026-10-22T22:57:46Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.43.5</generator>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=Thomas_algorithm,_locality&amp;diff=29122&amp;oldid=prev</id>
		<title>ASA: /* Локальность реализации алгоритма */</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=Thomas_algorithm,_locality&amp;diff=29122&amp;oldid=prev"/>
		<updated>2022-07-14T06:12:53Z</updated>

		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Локальность реализации алгоритма&lt;/span&gt;&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;col class=&quot;diff-marker&quot; /&gt;
				&lt;col class=&quot;diff-content&quot; /&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ru&quot;&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Предыдущая версия&lt;/td&gt;
				&lt;td colspan=&quot;2&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Версия от 06:12, 14 июля 2022&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot; id=&quot;mw-diff-left-l19&quot;&gt;Строка 19:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 19:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;На рис. 1 представлен профиль обращений в память для реализации точечного варианта прогонки. Данный профиль состоит из обращений к 5 массивам – трем диагоналям матрицы, вектору правых частей и результирующему вектору. Исходя из общего профиля, можно увидеть, что программа состоит из двух этапов – на первом выполняется последовательный перебор элементов 4-х массивов, на втором – также последовательный перебор, только в обратном порядке.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;На рис. 1 представлен профиль обращений в память для реализации точечного варианта прогонки. Данный профиль состоит из обращений к 5 массивам – трем диагоналям матрицы, вектору правых частей и результирующему вектору. Исходя из общего профиля, можно увидеть, что программа состоит из двух этапов – на первом выполняется последовательный перебор элементов 4-х массивов, на втором – также последовательный перебор, только в обратном порядке.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;−&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #ffe49c; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[file:tridiagonal_2.png|thumb|center|500px|Рисунок 2. Фрагмент общего профиля (выделенный зеленым цветом на рис. &lt;del style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;3&lt;/del&gt;)]]&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot; data-marker=&quot;+&quot;&gt;&lt;/td&gt;&lt;td style=&quot;color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #a3d3ff; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;[[file:tridiagonal_2.png|thumb|center|500px|Рисунок 2. Фрагмент общего профиля (выделенный зеленым цветом на рис. &lt;ins style=&quot;font-weight: bold; text-decoration: none;&quot;&gt;1&lt;/ins&gt;)]]&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;br&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Однако при более детальном рассмотрении можно заметить, что профиль устроен несколько сложнее (рис. 2). Для некоторых массивов на каждом шаге выполняется по несколько очень близких обращений, что приводит к улучшению как пространственной, так и временной локальности.&lt;/div&gt;&lt;/td&gt;&lt;td class=&quot;diff-marker&quot;&gt;&lt;/td&gt;&lt;td style=&quot;background-color: #f8f9fa; color: #202122; font-size: 88%; border-style: solid; border-width: 1px 1px 1px 4px; border-radius: 0.33em; border-color: #eaecf0; vertical-align: top; white-space: pre-wrap;&quot;&gt;&lt;div&gt;Однако при более детальном рассмотрении можно заметить, что профиль устроен несколько сложнее (рис. 2). Для некоторых массивов на каждом шаге выполняется по несколько очень близких обращений, что приводит к улучшению как пространственной, так и временной локальности.&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>ASA</name></author>
	</entry>
	<entry>
		<id>https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=Thomas_algorithm,_locality&amp;diff=29121&amp;oldid=prev</id>
		<title>ASA: Новая страница: «{{level-i}}  Основные авторы описания: Вад.В.Воеводин (#Описание локальности...»</title>
		<link rel="alternate" type="text/html" href="https://xn--80aecvaldz.xn--80ahdrnmvk.xn--p1ai/w/ru/index.php?title=Thomas_algorithm,_locality&amp;diff=29121&amp;oldid=prev"/>
		<updated>2022-07-14T06:09:21Z</updated>

		<summary type="html">&lt;p&gt;Новая страница: «{{level-i}}  Основные авторы описания: &lt;a href=&quot;/ru/%D0%A3%D1%87%D0%B0%D1%81%D1%82%D0%BD%D0%B8%D0%BA:VadimVV&quot; title=&quot;Участник:VadimVV&quot;&gt;Вад.В.Воеводин&lt;/a&gt; (#Описание локальности...»&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{level-i}}&lt;br /&gt;
&lt;br /&gt;
Основные авторы описания: [[Участник:VadimVV|Вад.В.Воеводин]] ([[#Описание локальности данных и вычислений|раздел 2]]), [[Участник:Teplov|А.М.Теплов]] (раздел [[#Масштабируемость алгоритма и его реализации|3]])&lt;br /&gt;
= Ссылки =&lt;br /&gt;
&lt;br /&gt;
Основной фрагмент реализации, на основе которого были получены количественные оценки, приведен [https://gitlab.srcc.msu.ru/shvets.pavel.srcc/locality/blob/master/benchmarks/tridiagonal/tridiagonal.h здесь] (функция Kernel).&lt;br /&gt;
&lt;br /&gt;
= Локальность данных и вычислений =&lt;br /&gt;
&lt;br /&gt;
Как видно по графу алгоритма, локальность данных по пространству хорошая - все аргументы, которые необходимы для операций, вычисляются &amp;quot;рядом&amp;quot;. Однако по времени локальность вычислений не столь хороша. Если данные задачи не помещаются в кэш, то вычисления в &amp;quot;верхнем левом углу&amp;quot; СЛАУ будут выполняться с постоянными промахами кэша. Отсюда может следовать одна из рекомендаций прикладникам, использующим прогонку, - нужно организовать все вычисления так, чтобы прогонки были &amp;quot;достаточно коротки&amp;quot; для помещения данных в кэш.&lt;br /&gt;
&lt;br /&gt;
При этом, однако, прогонка относится к таким последовательным алгоритмам, в которых локальность вычислений настолько велика, что является даже излишней&amp;lt;ref&amp;gt;Фролов А.В., Антонов А.С., Воеводин Вл.В., Теплов А.М. Сопоставление разных методов решения одной задачи по методике проекта Algowiki // Подана на конференцию &amp;quot;Параллельные вычислительные технологии (ПаВТ&amp;#039;2016)&amp;quot;.&amp;lt;/ref&amp;gt;. Из-за того, что данные, необходимые для выполнения основных операций прогонки, вычисляются в непосредственно предшествующим им операциях, возможность использования суперскалярности вычислительных ядер процессоров практически сводится на нет, что резко ухудшает эффективность выполнения прогонки даже на современных однопроцессорных и одноядерных системах.&lt;br /&gt;
&lt;br /&gt;
== Локальность реализации алгоритма ==&lt;br /&gt;
=== Структура обращений в память и качественная оценка локальности ===&lt;br /&gt;
&lt;br /&gt;
[[file:tridiagonal_1.png|thumb|center|700px|Рисунок 1. Прогонка, точечный вариант. Общий профиль обращений в память]]&lt;br /&gt;
&lt;br /&gt;
На рис. 1 представлен профиль обращений в память для реализации точечного варианта прогонки. Данный профиль состоит из обращений к 5 массивам – трем диагоналям матрицы, вектору правых частей и результирующему вектору. Исходя из общего профиля, можно увидеть, что программа состоит из двух этапов – на первом выполняется последовательный перебор элементов 4-х массивов, на втором – также последовательный перебор, только в обратном порядке.&lt;br /&gt;
&lt;br /&gt;
[[file:tridiagonal_2.png|thumb|center|500px|Рисунок 2. Фрагмент общего профиля (выделенный зеленым цветом на рис. 3)]]&lt;br /&gt;
&lt;br /&gt;
Однако при более детальном рассмотрении можно заметить, что профиль устроен несколько сложнее (рис. 2). Для некоторых массивов на каждом шаге выполняется по несколько очень близких обращений, что приводит к улучшению как пространственной, так и временной локальности.&lt;br /&gt;
&lt;br /&gt;
Таким образом, общий профиль обладает высокой пространственной локальностью (поскольку здесь доминируют последовательные переборы элементов) и средней временной (поскольку некоторые элементы сразу используются повторно).&lt;br /&gt;
&lt;br /&gt;
=== Количественная оценка локальности ===&lt;br /&gt;
&lt;br /&gt;
Условия запуска описаны [https://gitlab.srcc.msu.ru/shvets.pavel.srcc/locality/blob/master/README.md здесь].&lt;br /&gt;
&lt;br /&gt;
Первая оценка выполняется на основе характеристики daps, которая оценивает число выполненных обращений (чтений и записей) в память в секунду. Данная характеристика является аналогом оценки flops применительно к работе с памятью и является в большей степени оценкой производительности взаимодействия с памятью, чем оценкой локальности. Однако она служит хорошим источником информации, в том числе для сравнения с результатами по следующей характеристике cvg.&lt;br /&gt;
&lt;br /&gt;
На рисунке 3 приведены значения daps для реализаций распространенных алгоритмов, отсортированные по возрастанию (чем больше daps, тем в общем случае выше производительность). Для данной программы значения daps является достаточно неожиданным. Согласно качественному анализу, локальность обращений в память в этом случае достаточно высока. Однако daps оценивает производительность работы с памятью ниже, чем для теста RandomAccess! Такое различие между локальностью и производительностью встречается нечасто.&lt;br /&gt;
&lt;br /&gt;
При детальном рассмотрении исходного кода выяснились две причины такого поведения. Во-первых, итерации основного цикла являются зависимыми по памяти, то есть на очередной итерации используются данные, посчитанные на предыдущей. Похоже, что в данном случае эта зависимость значительно снижает эффективность работы с памятью, в то время как с точки зрения локальности данный случай является достаточно неплохим.&lt;br /&gt;
&lt;br /&gt;
Также выяснилось, что одна из операций деления неожиданно существенно замедляет выполнение программы. При замене этой операции на умножение время выполнения уменьшается в 2.5 раза, при этом ассемблерный код двух вариантов программы выглядел идентично (за исключением очевидной замены одной команды деления на команду умножения). &lt;br /&gt;
&lt;br /&gt;
[[file:tridiagonal_daps.png|thumb|center|700px|Рисунок 3. Сравнение значений оценки daps]]&lt;br /&gt;
&lt;br /&gt;
Такие особенности программы не отражаются в ее свойствах локальности, что и привело к такому существенному разрыву между оценкой локальности и производительностью работы с памятью.&lt;br /&gt;
&lt;br /&gt;
Вторая характеристика – cvg – предназначена для получения более машинно-независимой оценки локальности. Она определяет, насколько часто в программе необходимо подтягивать данные в кэш-память. Соответственно, чем меньше значение cvg, тем реже это нужно делать, и тем лучше локальность алгоритма. &lt;br /&gt;
&lt;br /&gt;
На рисунке 4 приведены значения cvg для того же набора реализаций, отсортированные по убыванию (чем меньше cvg, тем в общем случае выше локальность). В данном случае все предыдущие выводы подтверждаются – локальность оказывается достаточно высокой, что и было замечено согласно качественной оценке локальности.&lt;br /&gt;
&lt;br /&gt;
[[file:tridiagonal_cvg.png|thumb|center|700px|Рисунок 4. Сравнение значений оценки cvg]]&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;
Проведём исследование масштабируемости реализации алгоритма согласно [[Scalability methodology|методике]]. Исследование проводилось на суперкомпьютере &amp;quot;Ломоносов&amp;quot;&amp;lt;ref name=&amp;quot;Lom&amp;quot;&amp;gt;Воеводин Вл., Жуматий С., Соболев С., Антонов А., Брызгалов П., Никитенко Д., Стефанов К., Воеводин Вад. Практика суперкомпьютера «Ломоносов» // Открытые системы, 2012, N 7, С. 36-39.&amp;lt;/ref&amp;gt; [http://parallel.ru/cluster Суперкомпьютерного комплекса Московского университета].&lt;br /&gt;
&lt;br /&gt;
Набор и границы значений изменяемых [[Глоссарий#Параметры запуска|параметров запуска]] реализации алгоритма: &lt;br /&gt;
&lt;br /&gt;
*	число процессоров 1;&lt;br /&gt;
*	размер области [10240 : 1024000] с шагом 10240.&lt;br /&gt;
&lt;br /&gt;
В результате проведенных экспериментов был получен следующий диапазон [[Глоссарий#Эффективность реализации|эффективности реализации]] алгоритма:&lt;br /&gt;
&lt;br /&gt;
*	минимальная эффективность реализации 0.019%;&lt;br /&gt;
*	максимальная эффективность реализации 0.0255%.&lt;br /&gt;
&lt;br /&gt;
На следующих рисунках приведены графики [[Глоссарий#Производительность|производительности]] и эффективности выбранной реализации алгоритма в зависимости от изменяемых параметров запуска.&lt;br /&gt;
&lt;br /&gt;
[[file:Tridiag Perf.png|thumb|center|700px|Рисунок 5. Реализация алгоритма. Изменение производительности в зависимости от размера вектора.]]&lt;br /&gt;
[[file:Tridiag eff.png|thumb|center|700px|Рисунок 6. Реализация алгоритма. Изменение эффективности в зависимости от размера вектора.]]&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;. Использовались процессоры Intel Xeon X5570 с пиковой производительностью в 94 Гфлопс, а также компилятор Gnu 4.4.7. &lt;br /&gt;
На рисунках показана эффективность реализации алгоритма прогонки.&lt;br /&gt;
&lt;br /&gt;
[[file:Tridiag1 CPU user.png|thumb|center|700px|Рисунок 7. График загрузки CPU при выполнении алгоритма погонки]]&lt;br /&gt;
&lt;br /&gt;
На графике загрузки процессора видно, что почти все время работы программы уровень загрузки составляет около 4% в среднем. Это указывает на достаточно низкую нагрузку выполнения последовательного алгоритма на 8-ми ядерном процессоре. &lt;br /&gt;
&lt;br /&gt;
[[file:Tridiag1 FLops.png|thumb|center|700px|Рисунок 8. График операций с плавающей точкой в секунду при выполнении алгоритма прогонки]]&lt;br /&gt;
&lt;br /&gt;
На Рисунке 9 показан график количества операций с плавающей точкой в секунду. На графике видна общая низкая производительность вычислений, достигающая в пике 2,2 млн операций в секунду.&lt;br /&gt;
 [[file:Tridiag1 L1.png|thumb|center|700px|Рисунок 9. График кэш-промахов L1 в секунду при работе алгоритма прогонки]]&lt;br /&gt;
 &lt;br /&gt;
На графике кэш-промахов первого уровня видно, что число промахов достаточно низкое даже для одного ядра и находится на уровне 500 тыс/сек. Это указывает на достаточно хорошую локальность данных.&lt;br /&gt;
 [[file:Tridiag1 L3.png|thumb|center|700px|Рисунок 10. График кэш-промахов L3 в секунду при работе алгоритма прогонки]]&lt;br /&gt;
&lt;br /&gt;
На графике кэш-промахов третьего уровня видно, что число промахов все еще достаточно низкое для небольшого числа процессов и находится на уровне 80 тыс/сек. Отношение промахов L1/L3  около 6, что выше средних показателей по типичным задачам. Это также указывает на хорошую локальность вычислений. &lt;br /&gt;
[[file:Tridiag1 Mem Load.png|thumb|center|700px|Рисунок 11. График количества чтений из оперативной памяти при работе алгоритма прогонки]]&lt;br /&gt;
&lt;br /&gt;
На графике чтений из памяти на наблюдается достаточно высокая активность чтения из памяти процессами. Так как активно работает только один процесс, то и активность чтения соответствует максимальным значениям. Активность достаточно типична для приложений такого класса.&lt;br /&gt;
 [[file:Tridiag1 Mem Store.png|thumb|center|700px|Рисунок 12. График количества записей в оперативную память при работе алгоритма прогонки]]&lt;br /&gt;
&lt;br /&gt;
Активность записи в память достаточно низкая, это вполне ожидаемо для такого алгоритма, и так же указывает на достаточно высокую локальность вычислений.&lt;br /&gt;
 [[file:Tridiag1 Load Avg.png|thumb|center|700px|Рисунок 13. График числа процессов, ожидающих вхождения в стадию счета (Loadavg), при работе алгоритма прогонки]]&lt;br /&gt;
На графике числа процессов, ожидающих вхождения в стадию счета (Loadavg), видно, что на протяжении всей работы программы значение этого параметра постоянно и приблизительно равняется 1. Это свидетельствует о стабильной работе программы с работающим только одним процессом. &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;
&lt;br /&gt;
[[Категория:Статьи в работе]]&lt;br /&gt;
&lt;br /&gt;
[[En:Thomas algorithm, locality]]&lt;/div&gt;</summary>
		<author><name>ASA</name></author>
	</entry>
</feed>