Compare commits

...

10 commits

Author SHA1 Message Date
0054f7245c 2024-12-29 2024-12-29 10:39:47 +03:00
0cba400c21 2024-09-30 2024-10-01 18:02:31 +03:00
00acb3beeb 2024-08-31 2024-09-01 08:46:26 +03:00
a700572723 2024-07-31 2024-07-31 21:11:20 +03:00
fafb270621 2024-03-31 2024-03-31 02:14:43 +03:00
29d17ed877 2024-02-29 2024-02-29 22:56:43 +03:00
8dcb9dbd1e 2023-12-30 2023-12-30 23:55:12 +03:00
d9e59c1688 2023-11-30 2023-12-17 09:50:15 +03:00
6f960bda29 2023-09-30 2023-12-17 08:49:19 +03:00
ed71e6823d 2023-08-31 2023-12-17 08:22:17 +03:00
16 changed files with 125 additions and 117 deletions

View file

@ -3,9 +3,6 @@
<pre>
<a href='.'>.</a>
├─ <a href='jekyll_site'>jekyll_site</a>
│ ├─ <a href='jekyll_site/_includes'>_includes</a>
│ │ ├─ <a href='jekyll_site/_includes/counters_body.html'>counters_body.html</a>
│ │ └─ <a href='jekyll_site/_includes/counters_head.html'>counters_head.html</a>
│ ├─ <a href='jekyll_site/en'>en</a>
│ │ ├─ <a href='jekyll_site/en/2021'>2021</a>/<a href='jekyll_site/en/2021/12'>12</a>
│ │ │ ├─ <a href='jekyll_site/en/2021/12/10'>10</a>/<a href='jekyll_site/en/2021/12/10/optimizing-matrix-multiplication.md'>optimizing-matrix-multiplication.md</a>

View file

@ -1,4 +1,4 @@
© Головин Г.Г., 2021-2023
© Головин Г.Г., 2021-2024
Опубликовано под [Открытой лицензией 1.1](OPEN_LICENSE.txt)
@ -8,7 +8,7 @@
---
© Golovin G.G., translation from Russian, 2021-2023
© Golovin G.G., translation from Russian, 2021-2024
Published under the [Open License 1.1](OPEN_LICENSE.txt)

View file

@ -1,5 +1,5 @@
## Исходные тексты
- Используемые форматы — Markdown, Liquid, YAML.
- Инструмент сборки — Jekyll с помидорными темами оформления.
- Инструмент сборки — Jekyll и помидорные темы оформления.
- Управление процессами — Bash скрипты.

View file

@ -1,37 +1,34 @@
#!/bin/bash
echo "Сборка сайта в двух помидорных темах и оптимизация результатов."
milliseconds=$(date '+%s%3N')
rm -rf _site
rm -rf _site_older
rm -rf _site_color
echo "Сборка старого помидора."
mkdir -p _site_older
cp -r jekyll_site/_includes _site_older
cp -r jekyll_site/ru _site_older
cp -r jekyll_site/en _site_older
cp -r jekyll_site/ru/index.md _site_older
cp -r jekyll_site/_config_older.yml _site_older/_config.yml
cp -r jekyll_site/Gemfile_older _site_older/Gemfile
cd _site_older || exit
jekyll build
cp -r _site ..
cd ..
echo "Сборка цветного помидора."
mkdir -p _site_color
cp -r jekyll_site/_includes _site_color
cp -r jekyll_site/ru _site_color
cp -r jekyll_site/en _site_color
cp -r jekyll_site/ru/index.md _site_color
cp -r jekyll_site/_config_color.yml _site_color/_config.yml
cp -r jekyll_site/Gemfile_color _site_color/Gemfile
cd _site_color || exit
jekyll build
cp -r _site ../_site/color
cd ..
echo "Копирование без сборки."
time_ms="$(date '+%s%3N')"
# удаление каталогов предыдущей сборки, если таковые имеются
find . -maxdepth 1 -type d -name "_site*" -exec rm -rf {} \;
# сборка сайта в двух помидорных темах
function jekyll_build {
case "$1" in
"older") echo "Сборка старого помидора." ;;
"color") echo "Сборка цветного помидора." ;;
*) return ;; # две помидорные темы оформления
esac
mkdir -p "_site_$1"
cp -r "jekyll_site/ru" "_site_$1"
cp -r "jekyll_site/en" "_site_$1"
cp -r "jekyll_site/ru/index.md" "_site_$1"
cp -r "jekyll_site/_config_$1.yml" "_site_$1/_config.yml"
cp -r "jekyll_site/Gemfile_$1" "_site_$1/Gemfile"
cd "_site_$1" || return
jekyll build --disable-disk-cache --quiet
}
export -f jekyll_build
# запуск параллельной сборки сайта в двух помидорных темах оформления
printf 'jekyll_build "%s"\0' {older,color} | xargs -n1 -0 -P0 bash -c
# объединение двух сборок
cp -r _site_older/_site .
cp -r _site_color/_site ./_site/color
# копирование без сборки
cp -r jekyll_site/img _site
cp -r jekyll_site/robots.txt _site
echo "Оптимизация собранного контента."
# оптимизация собранного контента
cd _site || exit
cp -r assets/* .
rm -r assets
@ -39,13 +36,19 @@ rm -r color/assets/favicon.ico
cp -r color/assets/* .
rm -r color/assets
rm -r color/404.html
find . -type f -name '*.html' | sort -r | while read -r file; do
sed -i 's/layout-padding=""/layout-padding/g' "$file"
sed -i 's/ class="language-plaintext highlighter-rouge"//g' "$file"
sed -i 's/ class="language-java highlighter-rouge"//g' "$file"
sed -i 's/<div><div class="highlight"><pre class="highlight">/<div class="highlight"><pre class="highlight">/g' "$file"
sed -i 's/<\/code><\/pre><\/div><\/div>/<\/code><\/pre><\/div>/g' "$file"
sed -i 's/<hr \/>/<hr>/g' "$file"
sed -i -r 's/<img(.+) \/>/<img\1>/g' "$file"
done
echo "Время выполнения сборки: $(("$(date '+%s%3N')" - "$milliseconds")) мс."
rm -r color/return.html
# шаблоны для оптимизации ряда тегов
expr+=('s|layout-padding=""|layout-padding|g')
expr+=('s| class="language-plaintext highlighter-rouge"||g')
expr+=('s| class="language-java highlighter-rouge"||g')
expr+=('s|<div><div class="highlight">|<div class="highlight">|g')
expr+=('s|</pre></div></div>|</pre></div>|g')
expr+=('s|<hr />|<hr>|g')
expr+=('s|<img(.+) />|<img\1>|g')
# запуск параллельной обработки собранных страниц и оптимизация ряда тегов
find . -type f -name "*.html" -printf '%p\0' | xargs -I{} -n1 -0 -P0 bash -c \
"echo 'Оптимизация: {}' && sed -i -E $(printf " -e '%s'" "${expr[@]}") '{}'"
# переход в корень сайта для каталогов без заглавной страницы
find . -type d -exec cp -n return.html {}/index.html \;
rm -r return.html
echo "Общее время выполнения: $(($(date '+%s%3N') - time_ms)) мс."

View file

@ -1,18 +1,31 @@
# site parameters
# название сайта для подписи в футере
name: "Код с комментариями"
# подпись в футере для переведённых страниц
name_translated: "Code with comments"
# URL адрес сайта, включая протокол
url: "https://pomodoro3.mircloud.ru"
# подпапка этой сборки для относительных URL-ов
baseurl: "/color"
homepage_url: "https://git.org.ru/pomodoro/3"
homepage_name: "GIT.ORG.RU"
# ссылка в верхнем левом углу заглавных страниц
homepage_url: "https://gitea.com/pomodoro/3"
# представление ссылки
homepage_name: "GITEA"
# подпапка альтернативной сборки
older_tomato_baseurl: ""
# часовой пояс для формата даты ISO-8601
timezone: "Europe/Moscow"
# имя автора для SEO-разметки и подписи в футере
author: "Головин Г.Г."
# транслитерация имени автора для переведённых страниц
author_translated: "Golovin G.G."
# дополнение к подписи в футере для переведённых страниц
translation_caption: "translation from Russian"
# build parameters
disable_disk_cache: true
# номера счётчиков для страниц
live_internet: "pomodoro"
yandex_metrika: "95699483"
# тема оформления для сборки
theme: color-tomato-theme
# макет для сборки
defaults:
- scope:
path: ""

View file

@ -1,18 +1,31 @@
# site parameters
# название сайта для подписи в футере
name: "Код с комментариями"
# подпись в футере для переведённых страниц
name_translated: "Code with comments"
# URL адрес сайта, включая протокол
url: "https://pomodoro3.mircloud.ru"
# подпапка этой сборки для относительных URL-ов
baseurl: ""
homepage_url: "https://git.org.ru/pomodoro/3"
homepage_name: "GIT.ORG.RU"
# ссылка в верхнем левом углу заглавных страниц
homepage_url: "https://gitea.com/pomodoro/3"
# представление ссылки
homepage_name: "GITEA"
# подпапка альтернативной сборки
color_tomato_baseurl: "/color"
# часовой пояс для формата даты ISO-8601
timezone: "Europe/Moscow"
# имя автора для SEO-разметки и подписи в футере
author: "Головин Г.Г."
# транслитерация имени автора для переведённых страниц
author_translated: "Golovin G.G."
# дополнение к подписи в футере для переведённых страниц
translation_caption: "translation from Russian"
# build parameters
disable_disk_cache: true
# номера счётчиков для страниц
live_internet: "pomodoro"
yandex_metrika: "95699483"
# тема оформления для сборки
theme: older-tomato-theme
# макет для сборки
defaults:
- scope:
path: ""

View file

@ -1,2 +0,0 @@
<noscript><div><img src="https://mc.yandex.ru/watch/87058815" style="position:absolute; left:-9999px;" alt=""></div></noscript>
<!-- /Yandex.Metrika counter -->

View file

@ -1,16 +0,0 @@
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-148X3KY8JP"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-148X3KY8JP');
</script>
<!-- Yandex.Metrika counter -->
<script>
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)};
m[i].l=1*new Date();for(var j=0;j<document.scripts.length;j++){if(document.scripts[j].src===r){return;}}
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)})
(window,document,"script","https://mc.yandex.ru/metrika/tag.js","ym");
ym(87058815,"init",{clickmap:true,trackLinks:true,accurateTrackBounce:true,webvisor:true});
</script>

View file

@ -24,7 +24,7 @@ and depends on the execution environment.
*Further optimization: [Matrix multiplication in parallel streams]({{ '/en/2022/02/09/matrix-multiplication-parallel-streams.html' | relative_url }}).*
## Row-wise algorithm {#row-wise-algorithm}
{% include heading.html text="Row-wise algorithm" hash="row-wise-algorithm" %}
The outer loop bypasses the rows of the first matrix `L`, then there is a loop across the *common side*
of the two matrices `M` and it is followed by a loop across the columns of the second matrix `N`.
@ -57,7 +57,7 @@ public static int[][] matrixMultiplicationLMN(int l, int m, int n, int[][] a, in
}
```
## Layer-wise algorithm {#layer-wise-algorithm}
{% include heading.html text="Layer-wise algorithm" hash="layer-wise-algorithm" %}
The outer loop bypasses the *common side* of the two matrices `M`, then there is a loop across the rows
of the first matrix `L`, and it is followed by a loop across the columns of the second matrix `N`.
@ -90,7 +90,7 @@ public static int[][] matrixMultiplicationMLN(int l, int m, int n, int[][] a, in
}
```
### Other algorithms {#other-algorithms}
{% include heading.html text="Other algorithms" hash="other-algorithms" type="3" %}
The bypass of the columns of the second matrix `N` occurs before the bypass of the *common side* of the
two matrices `M` and/or before the bypass of the rows of the first matrix `L`.
@ -139,7 +139,7 @@ public static int[][] matrixMultiplicationNML(int l, int m, int n, int[][] a, in
{% endcapture %}
{%- include collapsed_block.html summary="Code without comments" content=collapsed_md -%}
## Comparing algorithms {#comparing-algorithms}
{% include heading.html text="Comparing algorithms" hash="comparing-algorithms" %}
To check, we take two matrices `A=[500×700]` and `B=[700×450]`, filled with random numbers. First, we
compare the correctness of the implementation of the algorithms all results obtained must match.

View file

@ -20,7 +20,7 @@ be reduced by more than two times. To check, let's take two rectangular matrices
*Further optimization: [Winograd Strassen algorithm]({{ '/en/2022/02/11/winograd-strassen-algorithm.html' | relative_url }}).*
## Parallel stream {#parallel-stream}
{% include heading.html text="Parallel stream" hash="parallel-stream" %}
We bypass the rows of the first matrix `L` in parallel mode. In each thread there are two nested loops:
across the *common side* of two matrices `M` and across the columns of the second matrix `N`. Processing
@ -54,7 +54,7 @@ public static int[][] parallelMatrixMultiplication(int l, int m, int n, int[][]
}
```
## Three nested loops {#three-nested-loops}
{% include heading.html text="Three nested loops" hash="three-nested-loops" %}
We take the *optimized* variant of algorithm, that uses cache of the execution environment better
than others. The outer loop bypasses the rows of the first matrix `L`, then there is a loop across
@ -88,7 +88,7 @@ public static int[][] sequentialMatrixMultiplication(int l, int m, int n, int[][
}
```
## Testing {#testing}
{% include heading.html text="Testing" hash="testing" %}
To check, we take two matrices `A=[900×1000]` and `B=[1000×750]`, filled with random numbers.
First, we compare the correctness of the implementation of the two algorithms matrix products
@ -156,7 +156,7 @@ Stream | 113 | 144 | 117 | 114 | 114 | 117 | 120 | 125 | 111 | 113 || 118
Loops | 1357 | 530 | 551 | 569 | 535 | 538 | 525 | 517 | 518 | 514 || 615
```
## Comparing algorithms {#comparing-algorithms}
{% include heading.html text="Comparing algorithms" hash="comparing-algorithms" %}
On an eight-core Linux x64 computer, we create a Windows x64 virtual machine for tests. All
other things being equal, in the settings, we change the number of processors. We run the

View file

@ -26,7 +26,7 @@ environment. Let's compare the operating time of two algorithms.
*Algorithm using three nested loops: [Optimizing matrix multiplication]({{ '/en/2021/12/10/optimizing-matrix-multiplication.html' | relative_url }}).*
## Algorithm description {#algorithm-description}
{% include heading.html text="Algorithm description" hash="algorithm-description" %}
Matrices must be the same size. We partition each matrix into 4 equally sized blocks. The blocks
must be square, therefore if this is not the case, then first we supplement the matrices with zero
@ -56,7 +56,7 @@ Blocks of the resulting matrix.
{% include image_svg.html src="/img/sums3.svg" style="width:240pt; height:33pt;"
alt="{\displaystyle{\begin{pmatrix}C_{11}&C_{12}\\C_{21}&C_{22}\end{pmatrix}}={\begin{pmatrix}P_{2}+P_{3}&T_{1}+P_{5}+P_{6}\\T_{2}-P_{7}&T_{2}+P_{5}\end{pmatrix}}.}" %}
## Hybrid algorithm {#hybrid-algorithm}
{% include heading.html text="Hybrid algorithm" hash="hybrid-algorithm" %}
We partition each matrix `A` and `B` into 4 equally sized blocks and, if necessary, we supplement
the missing parts with zeros. Perform 15 summations and 7 multiplications over the blocks we get
@ -101,13 +101,13 @@ public static int[][] multiplyMatrices(int n, int brd, int[][] a, int[][] b) {
// multiplication of blocks in parallel streams
IntStream.range(0, 7).parallel().forEach(i -> {
switch (i) { // recursive calls
case 0: p[i] = multiplyMatrices(m, brd, s2, s6); break;
case 1: p[i] = multiplyMatrices(m, brd, a11, b11); break;
case 2: p[i] = multiplyMatrices(m, brd, a12, b21); break;
case 3: p[i] = multiplyMatrices(m, brd, s3, s7); break;
case 4: p[i] = multiplyMatrices(m, brd, s1, s5); break;
case 5: p[i] = multiplyMatrices(m, brd, s4, b22); break;
case 6: p[i] = multiplyMatrices(m, brd, a22, s8); break;
case 0 -> p[i] = multiplyMatrices(m, brd, s2, s6);
case 1 -> p[i] = multiplyMatrices(m, brd, a11, b11);
case 2 -> p[i] = multiplyMatrices(m, brd, a12, b21);
case 3 -> p[i] = multiplyMatrices(m, brd, s3, s7);
case 4 -> p[i] = multiplyMatrices(m, brd, s1, s5);
case 5 -> p[i] = multiplyMatrices(m, brd, s4, b22);
case 6 -> p[i] = multiplyMatrices(m, brd, a22, s8);
}
});
// summation of blocks
@ -169,7 +169,7 @@ private static int[][] putQuadrants(int m, int n,
{% endcapture %}
{%- include collapsed_block.html summary="Helper methods" content=collapsed_md -%}
## Nested loops {#nested-loops}
{% include heading.html text="Nested loops" hash="nested-loops" %}
To supplement the previous algorithm and to compare with it, we take the *optimized* variant of nested
loops, that uses cache of the execution environment better than others processing of the rows of the
@ -201,7 +201,7 @@ public static int[][] simpleMultiplication(int n, int[][] a, int[][] b) {
}
```
## Testing {#testing}
{% include heading.html text="Testing" hash="testing" %}
To check, we take two square matrices `A=[1000×1000]` and `B=[1000×1000]`, filled with random numbers.
Take the minimum block size `[200×200]` elements. First, we compare the correctness of the implementation
@ -270,7 +270,7 @@ Hybrid algorithm | 196 | 177 | 156 | 205 | 154 | 165 | 133 | 118 | 132 | 134 ||
Nested loops | 165 | 164 | 168 | 167 | 168 | 168 | 170 | 179 | 173 | 168 || 169
```
## Comparing algorithms {#comparing-algorithms}
{% include heading.html text="Comparing algorithms" hash="comparing-algorithms" %}
On an eight-core Linux x64 computer, execute the above test 100 times instead of 10. Take the minimum
block size `[brd=200]` elements. Change only `n` sizes of both matrices `A=[n×n]` and `B=[n×n]`. Get

View file

@ -22,7 +22,7 @@ date: 2021.12.09
*Дальнейшая оптимизация: [Умножение матриц в параллельных потоках]({{ '/ru/2022/02/08/matrix-multiplication-parallel-streams.html' | relative_url }}).*
## Построчный алгоритм {#row-wise-algorithm}
{% include heading.html text="Построчный алгоритм" hash="row-wise-algorithm" %}
Внешний цикл обходит строки первой матрицы `L`, далее идёт цикл по *общей стороне* двух матриц `M`
и за ним цикл по колонкам второй матрицы `N`. Запись в результирующую матрицу происходит построчно,
@ -55,7 +55,7 @@ public static int[][] matrixMultiplicationLMN(int l, int m, int n, int[][] a, in
}
```
## Послойный алгоритм {#layer-wise-algorithm}
{% include heading.html text="Послойный алгоритм" hash="layer-wise-algorithm" %}
Внешний цикл обходит *общую сторону* двух матриц `M`, далее идёт цикл по строкам первой матрицы
`L` и за ним цикл по колонкам второй матрицы `N`. Запись в результирующую матрицу происходит слоями,
@ -88,7 +88,7 @@ public static int[][] matrixMultiplicationMLN(int l, int m, int n, int[][] a, in
}
```
### Прочие алгоритмы {#other-algorithms}
{% include heading.html text="Прочие алгоритмы" hash="other-algorithms" type="3" %}
Обход колонок второй матрицы `N` происходит перед обходом *общей стороны* двух матриц `M`
и/или перед обходом строк первой матрицы `L`.
@ -137,7 +137,7 @@ public static int[][] matrixMultiplicationNML(int l, int m, int n, int[][] a, in
{% endcapture %}
{%- include collapsed_block.html summary="Код без комментариев" content=collapsed_md -%}
## Сравнение алгоритмов {#comparing-algorithms}
{% include heading.html text="Сравнение алгоритмов" hash="comparing-algorithms" %}
Для проверки возьмём две матрицы `A=[500×700]` и `B=[700×450]`, заполненные случайными числами.
Сначала сравниваем между собой корректность реализации алгоритмов все полученные результаты

View file

@ -19,7 +19,7 @@ date: 2022.02.08
*Дальнейшая оптимизация: [Алгоритм Винограда Штрассена]({{ '/ru/2022/02/10/winograd-strassen-algorithm.html' | relative_url }}).*
## Параллельный поток {#parallel-stream}
{% include heading.html text="Параллельный поток" hash="parallel-stream" %}
Строки первой матрицы `L` обходим в параллельном режиме. Внутри каждого потока два вложенных цикла:
по *общей стороне* двух матриц `M` и по колонкам второй матрицы `N`. Обработка строк результирующей
@ -53,7 +53,7 @@ public static int[][] parallelMatrixMultiplication(int l, int m, int n, int[][]
}
```
## Три вложенных цикла {#three-nested-loops}
{% include heading.html text="Три вложенных цикла" hash="three-nested-loops" %}
Возьмём оптимизированный вариант алгоритма, который лучше прочих использует кеш среды выполнения.
Внешний цикл обходит строки первой матрицы `L`, далее идёт цикл по *общей стороне* двух матриц `M`
@ -87,7 +87,7 @@ public static int[][] sequentialMatrixMultiplication(int l, int m, int n, int[][
}
```
## Тестирование {#testing}
{% include heading.html text="Тестирование" hash="testing" %}
Для проверки возьмём две матрицы: `A=[900×1000]` и `B=[1000×750]`, заполненные случайными числами.
Сначала сравниваем между собой корректность реализации двух алгоритмов произведения матриц
@ -155,7 +155,7 @@ private static void benchmark(String title, int steps, Runnable runnable) {
Циклы | 1357 | 530 | 551 | 569 | 535 | 538 | 525 | 517 | 518 | 514 || 615
```
## Сравнение алгоритмов {#comparing-algorithms}
{% include heading.html text="Сравнение алгоритмов" hash="comparing-algorithms" %}
На восьмиядерном компьютере Linux x64 создаём для тестов виртуальную машину Windows x64. При
прочих равных условиях в настройках меняем количество процессоров. Запускаем вышеописанный

View file

@ -24,7 +24,7 @@ date: 2022.02.10
*Алгоритм на трёх вложенных циклах: [Оптимизация умножения матриц]({{ '/ru/2021/12/09/optimizing-matrix-multiplication.html' | relative_url }}).*
## Описание алгоритма {#algorithm-description}
{% include heading.html text="Описание алгоритма" hash="algorithm-description" %}
Матрицы должны быть одинакового размера. Разделяем каждую матрицу на 4 равных блока. Блоки должны быть
квадратными, поэтому если это не так, тогда сначала дополняем матрицы нулевыми строками и столбцами,
@ -53,7 +53,7 @@ alt="{\displaystyle{\begin{aligned}T_{1}&=P_{1}+P_{2};\\T_{2}&=T_{1}+P_{4}.\end{
{% include image_svg.html src="/img/sums3.svg" style="width:240pt; height:33pt;"
alt="{\displaystyle{\begin{pmatrix}C_{11}&C_{12}\\C_{21}&C_{22}\end{pmatrix}}={\begin{pmatrix}P_{2}+P_{3}&T_{1}+P_{5}+P_{6}\\T_{2}-P_{7}&T_{2}+P_{5}\end{pmatrix}}.}" %}
## Гибридный алгоритм {#hybrid-algorithm}
{% include heading.html text="Гибридный алгоритм" hash="hybrid-algorithm" %}
Каждую матрицу `A` и `B` делим на 4 *равных* блока, при необходимости дополняем недостающие части
нулями. Выполняем 15 сложений и 7 умножений над блоками получаем 4 блока матрицы `C`. Убираем
@ -97,13 +97,13 @@ public static int[][] multiplyMatrices(int n, int brd, int[][] a, int[][] b) {
// перемножаем блоки в параллельных потоках
IntStream.range(0, 7).parallel().forEach(i -> {
switch (i) { // рекурсивные вызовы
case 0: p[i] = multiplyMatrices(m, brd, s2, s6); break;
case 1: p[i] = multiplyMatrices(m, brd, a11, b11); break;
case 2: p[i] = multiplyMatrices(m, brd, a12, b21); break;
case 3: p[i] = multiplyMatrices(m, brd, s3, s7); break;
case 4: p[i] = multiplyMatrices(m, brd, s1, s5); break;
case 5: p[i] = multiplyMatrices(m, brd, s4, b22); break;
case 6: p[i] = multiplyMatrices(m, brd, a22, s8); break;
case 0 -> p[i] = multiplyMatrices(m, brd, s2, s6);
case 1 -> p[i] = multiplyMatrices(m, brd, a11, b11);
case 2 -> p[i] = multiplyMatrices(m, brd, a12, b21);
case 3 -> p[i] = multiplyMatrices(m, brd, s3, s7);
case 4 -> p[i] = multiplyMatrices(m, brd, s1, s5);
case 5 -> p[i] = multiplyMatrices(m, brd, s4, b22);
case 6 -> p[i] = multiplyMatrices(m, brd, a22, s8);
}
});
// суммируем блоки
@ -165,7 +165,7 @@ private static int[][] putQuadrants(int m, int n,
{% endcapture %}
{%- include collapsed_block.html summary="Вспомогательные методы" content=collapsed_md -%}
## Вложенные циклы {#nested-loops}
{% include heading.html text="Вложенные циклы" hash="nested-loops" %}
Для дополнения предыдущего алгоритма и для сравнения с ним же будем использовать *оптимизированный*
вариант вложенных циклов, который лучше прочих использует кеш среды выполнения обработка строк
@ -197,7 +197,7 @@ public static int[][] simpleMultiplication(int n, int[][] a, int[][] b) {
}
```
## Тестирование {#testing}
{% include heading.html text="Тестирование" hash="testing" %}
Для проверки возьмём две квадратные матрицы `A=[1000×1000]` и `B=[1000×1000]`, заполненные случайными
числами. Минимальный размер блока возьмём `[200×200]` элементов. Сначала сравниваем между собой
@ -266,7 +266,7 @@ private static void benchmark(String title, int steps, Runnable runnable) {
Вложенные циклы | 165 | 164 | 168 | 167 | 168 | 168 | 170 | 179 | 173 | 168 || 169
```
## Сравнение алгоритмов {#comparing-algorithms}
{% include heading.html text="Сравнение алгоритмов" hash="comparing-algorithms" %}
На восьмиядерном компьютере Linux x64 запускаем вышеописанный тест 100 раз вместо 10. Минимальный
размер блока берём `[brd=200]`. Изменяем только `n` размеры обеих матриц `A=[n×n]` и `B=[n×n]`.

View file

@ -1,5 +1,5 @@
#!/bin/bash
echo "Подготовка архива для последующего развёртывания."
echo "Создание архива для последующего развёртывания."
cd _site || exit
rm -rf ../pomodoro3.zip
7z a ../pomodoro3.zip ./*
7z a ../pomodoro3.zip . | grep -E '\S'

View file

@ -1,4 +1,4 @@
#!/bin/bash
echo "Локальное развёртывание для проверки корректности сборки."
jekyll serve --skip-initial-build --disable-disk-cache --host localhost
jekyll serve --skip-initial-build --no-watch --disable-disk-cache --host localhost
echo "Адрес сервера: http://localhost:4000"