<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Organizacja i Architektura systemów - 2023 on Side Effects</title><link>https://marcinklimek.github.io/student/2023-arch/</link><description>Recent content in Organizacja i Architektura systemów - 2023 on Side Effects</description><generator>Hugo -- gohugo.io</generator><language>en</language><atom:link href="https://marcinklimek.github.io/student/2023-arch/index.xml" rel="self" type="application/rss+xml"/><item><title>Test</title><link>https://marcinklimek.github.io/student/2023-arch/2023-05-27-test-studenci/</link><pubDate>Tue, 25 Apr 2023 19:13:33 +0200</pubDate><guid>https://marcinklimek.github.io/student/2023-arch/2023-05-27-test-studenci/</guid><description>&lt;h3 id="rozpisać-kolejne-kroki-konwersji-na-liczbę-w-notacji-binarnej-za-pomocą-metody-z-resztą">Rozpisać kolejne kroki konwersji na liczbę w notacji binarnej za pomocą metody z resztą:&lt;/h3>
&lt;pre>&lt;code>Przykład:
liczba: 108
108 : 2 = 54 (reszta: 0)
54 : 2 = 27 (reszta: 0)
27 : 2 = 13 (reszta: 1)
13 : 2 = 6 (reszta: 1)
6 : 2 = 3 (reszta: 0)
3 : 2 = 1 (reszta: 1)
1 : 2 = 0 (reszta: 1)
&lt;/code>&lt;/pre>
&lt;p>&lt;strong>Liczby do zamiany:&lt;/strong>&lt;/p></description><content:encoded><![CDATA[<h3 id="rozpisać-kolejne-kroki-konwersji-na-liczbę-w-notacji-binarnej-za-pomocą-metody-z-resztą">Rozpisać kolejne kroki konwersji na liczbę w notacji binarnej za pomocą metody z resztą:</h3>
<pre><code>Przykład:
liczba: 108

108   : 2 = 54   (reszta: 0)
54    : 2 = 27   (reszta: 0)
27    : 2 = 13   (reszta: 1)
13    : 2 = 6    (reszta: 1)
6     : 2 = 3    (reszta: 0)
3     : 2 = 1    (reszta: 1)
1     : 2 = 0    (reszta: 1)
</code></pre>
<p><strong>Liczby do zamiany:</strong></p>
<pre><code>1. 91
2. 2023
</code></pre>
<h4 id="zamiana-na-wartości-szesnastkowe-grupami-po-4-bity">Zamiana na wartości szesnastkowe (grupami po 4 bity)</h4>
<pre><code>Przykład:
liczba: 46893

1011 0111 0010 110
   B    7    2    D
</code></pre>
<p><strong>Liczby do zamiany:</strong></p>
<pre><code>1. 91
2. 2023
</code></pre>
<h3 id="przechowywanie-danych">Przechowywanie danych</h3>
<p><strong>Ile bitów jest potrzebnych na zapisanie liczby ?</strong></p>
<pre><code>139 - 
255 -  
881 -  
513 - 
</code></pre>
<h3 id="rejestr">Rejestr</h3>
<p><strong>Co to jest rejestr w procesorze?</strong></p>
<p><em>Proszę zaznaczyć właściwe odpowiedzi</em></p>
<pre><code>[ ] Obszar w pamięci RAM, który jest używany do przechowywania danych.
[ ] Element, który przechowuje adresy pamięci dla instrukcji procesora.
[ ] Komponent procesora odpowiedzialny za wykonywanie instrukcji.
[ ] Specjalna jednostka pamięci przechowująca dane bezpośrednio w procesorze do szybkiego dostępu.
[ ] Miejsce, gdzie procesor przechowuje swój stan.
[ ] fizyczne miejsce do przechowywania danych na dysku twardym
</code></pre>
<h3 id="nadmiar-i-niedomiar">Nadmiar i niedomiar</h3>
<ul>
<li><strong>Czy wynik operacji mieści się w 8-bitowym rejestrze? (nadmiar czy niedomiar)</strong></li>
<li><strong>Ile bitów potrzeba do reprezentacji wyniku?</strong></li>
</ul>
<ol>
<li>
<p>Dodawanie:</p>
<pre><code> A = 139
 B = 255
 A + B = 
</code></pre>
</li>
<li>
<p>Dodawanie:</p>
<pre><code> A = 139
 B = 117
 A + B =
</code></pre>
</li>
<li>
<p>Odejmowanie:</p>
<pre><code> A = 881
 B = 513
 A - B = 
</code></pre>
</li>
</ol>
<h3 id="liczby-ujemne">Liczby ujemne</h3>
<pre><code>Przykład:
 Zapisać liczbę -2 w 10-bitowym rejestrze, używamy kodu U2 (Uzupełnienie do 2):

    -2 = 1111111110
</code></pre>
<p><strong>Liczba do konwersji:</strong></p>
<pre><code>-19
</code></pre>
<h3 id="notacja-zmiennoprzecinkowa">Notacja zmiennoprzecinkowa</h3>
<p><strong>Z jakich elementów składa się liczba w notacji IEEE-754?</strong></p>
<h3 id="kolejność-bajtów">Kolejność bajtów</h3>
<p>Liczba 1278471395 zapisana jest w pamięci w kolejnych komórkach w nastepujący sposób:</p>
<pre><code>4c 33 ec e3
</code></pre>
<p><strong>Jaka to jest kolejność bajtów?</strong></p>
<h3 id="instrukcje">Instrukcje</h3>
<ol>
<li>Co to są instrukcje SIMD?</li>
<li>Do czego służą?</li>
</ol>
<h3 id="architektura">Architektura</h3>
<ol>
<li>Z jakich elmentów składa się architektura von Neumana?</li>
<li>Czym różni się od niej architektura Harwardzka?</li>
<li>Gdzie stosowana jest architektura Harwardzka?</li>
</ol>
<h3 id="cykl-rozkazowy">Cykl rozkazowy</h3>
<p><em>Proszę zaznaczyć właściwe odpowiedzi</em></p>
<p><strong>Co to jest potok rozkazowy w kontekście architektury komputera?</strong></p>
<pre><code>[ ] Mechanizm operacyjny pozwalający na równoległe wykonanie wielu rozkazów
[ ] Proces tworzenia oprogramowania
[ ] Metoda przechowywania danych w komputerze
[ ] Technika szyfrowania danych
</code></pre>
<p><strong>Który z poniższych stanowi główny cel potoku rozkazowego?</strong></p>
<pre><code>[ ] Zwiększenie przepustowości
[ ] Zmniejszenie zużycia energii przez komputer
[ ] Zwiększenie prędkości taktowania procesora
[ ] Zwiększenie pojemności pamięci RAM
</code></pre>
<p><strong>Jakie jest zastosowanie potoku rozkazowego w architekturze komputera?</strong></p>
<pre><code>[ ] Rozdzielenie procesu na fazy
[ ] Zwiększenie szybkości procesora
[ ] Zarządzanie pamięcią komputera
[ ] Wszystkie powyższe
</code></pre>
<p><strong>Jaki jest efekt potoku rozkazowego na wydajność systemu komputerowego?</strong></p>
<pre><code>[ ] Zwiększa wydajność poprzez równoległe wykonywanie instrukcji
[ ] Zmniejsza wydajność poprzez zwiększanie złożoności obliczeń
[ ] Nie wpływa na wydajność systemu komputerowego
[ ] Zwiększa wydajność poprzez zwiększenie szybkości taktowania
</code></pre>
<p><strong>Która z poniższych jest wadą potoku rozkazowego?</strong></p>
<pre><code>[ ] Efekt Hazardu
[ ] Zwiększenie szybkości procesora
[ ] Zwiększenie przepustowości
[ ] Równoległe wykonanie instrukcji
</code></pre>
<h3 id="potok-rozkazowy">Potok rozkazowy</h3>
<ol>
<li>Wymień rodzaje hazardów.</li>
<li>Jak można je eliminować?</li>
<li>Maksymalnie skrótowo opisz hazard, jaki był symulowany w zadaniu lab_07 - część pierwsza (bez predyktora)</li>
</ol>
]]></content:encoded></item><item><title>Zadania</title><link>https://marcinklimek.github.io/student/2023-arch/2023-05-27-lab_sobota_niedziela_28/</link><pubDate>Tue, 25 Apr 2023 18:13:33 +0200</pubDate><guid>https://marcinklimek.github.io/student/2023-arch/2023-05-27-lab_sobota_niedziela_28/</guid><description>&lt;p>&lt;strong>Lab_06:&lt;/strong>&lt;/p>
&lt;p>Ćwiczenie:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>Proszę uruchomić pierwszy program&lt;/p>
&lt;p>$lab_06_a.exe&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Proszę opisać kolejne cykle rozkazowe, jakie wykonuje procesor.&lt;/p>
&lt;/li>
&lt;li>
&lt;p>Należy zamieścić wynik działania programu w sprawozdaniu.&lt;/p>
&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;span class="lnt">6
&lt;/span>&lt;span class="lnt">7
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">memory = [10, 6, 7, 2, 1, 0, 0]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">instructions = [
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (&amp;#34;LOAD&amp;#34;, 0, 0),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (&amp;#34;LOAD&amp;#34;, 1, 2),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (&amp;#34;ADD&amp;#34;, 0, 1),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (&amp;#34;STORE&amp;#34;, 0, 0),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;ol start="4">
&lt;li>Proszę uruchomić drugi program
&lt;code>$lab_06_b.exe&lt;/code>&lt;/li>
&lt;li>Należy zamieścić wynik działania programu w sprawozdaniu.&lt;/li>
&lt;/ol>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-fallback" data-lang="fallback">&lt;span class="line">&lt;span class="cl">memory = [10, 6, 7, 2, 1, 0, 0]
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">instructions = [
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (&amp;#34;LOAD&amp;#34;, 0, 0),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (&amp;#34;LOAD&amp;#34;, 1, 2),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (&amp;#34;ADD&amp;#34;, 0, 1),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (&amp;#34;STORE&amp;#34;, 0, 0),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (&amp;#34;LOAD&amp;#34;, 3, 1),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (&amp;#34;LOAD&amp;#34;, 2, 3),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (&amp;#34;SUB&amp;#34;, 3, 2),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (&amp;#34;STORE&amp;#34;, 1, 3),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> (&amp;#34;JNZERO&amp;#34;, 3, -9),
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">]
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>&lt;strong>Lab_07&lt;/strong>&lt;/p></description><content:encoded><![CDATA[<p><strong>Lab_06:</strong></p>
<p>Ćwiczenie:</p>
<ol>
<li>
<p>Proszę uruchomić pierwszy program</p>
<p>$lab_06_a.exe</p>
</li>
<li>
<p>Proszę opisać kolejne cykle rozkazowe, jakie wykonuje procesor.</p>
</li>
<li>
<p>Należy zamieścić wynik działania programu w sprawozdaniu.</p>
</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">memory = [10, 6, 7, 2, 1, 0, 0]
</span></span><span class="line"><span class="cl">instructions = [
</span></span><span class="line"><span class="cl">    (&#34;LOAD&#34;,  0, 0),
</span></span><span class="line"><span class="cl">    (&#34;LOAD&#34;,  1, 2),
</span></span><span class="line"><span class="cl">    (&#34;ADD&#34;,   0, 1),
</span></span><span class="line"><span class="cl">    (&#34;STORE&#34;, 0, 0),
</span></span><span class="line"><span class="cl">]
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="4">
<li>Proszę uruchomić drugi program
<code>$lab_06_b.exe</code></li>
<li>Należy zamieścić wynik działania programu w sprawozdaniu.</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">memory = [10, 6, 7, 2, 1, 0, 0]
</span></span><span class="line"><span class="cl">instructions = [
</span></span><span class="line"><span class="cl">    (&#34;LOAD&#34;,  0, 0),
</span></span><span class="line"><span class="cl">    (&#34;LOAD&#34;,  1, 2),
</span></span><span class="line"><span class="cl">    (&#34;ADD&#34;,   0, 1),
</span></span><span class="line"><span class="cl">    (&#34;STORE&#34;, 0, 0),
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    (&#34;LOAD&#34;,  3, 1),
</span></span><span class="line"><span class="cl">    (&#34;LOAD&#34;,  2, 3),
</span></span><span class="line"><span class="cl">    (&#34;SUB&#34;,   3, 2),
</span></span><span class="line"><span class="cl">    (&#34;STORE&#34;, 1, 3),
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    (&#34;JNZERO&#34;, 3, -9),
</span></span><span class="line"><span class="cl">]
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>Lab_07</strong></p>
<ol>
<li>Bez włączonej predykcji</li>
</ol>
<p>Proszę uruchomić każdy z programów.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">lab_07.exe &lt;num_pipelines&gt; &lt;use_predictor&gt; &lt;test_program&gt;
</span></span><span class="line"><span class="cl">             &lt;1-12&gt;          &lt;True/False&gt;       &lt;1-3&gt;
</span></span></code></pre></td></tr></table>
</div>
</div><p>Na przykład:
<code>$ lab_07.exe 4 false 1   -&gt; Uruchomienie programu testowego nr 1, bez predyktora, z 4 potokami</code></p>
<p>W sprawozdaniu:</p>
<ul>
<li>Ile cykli wykonywał się każdy program?</li>
<li>Dlaczego wystąpił pierwszy stall w każdym z programów?</li>
</ul>
<p>Kolejno należy zmieniać ilość dostępnych potoków, od 1 do 5. Proszę opisać jak zmieniał się czas wykonania (ilość cykli). Z czego to może wynikać.
Dla każdego przypadku proszę podać końcową zawartość pamięci. Na przykład:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Memory:
</span></span><span class="line"><span class="cl">4, 0, 4, 0, 4, 7, 3, 2, 9, 7, 1, 1
</span></span></code></pre></td></tr></table>
</div>
</div><ol>
<li>Z włączoną predykcją</li>
</ol>
<p>Na przykład:
<code>$ lab_07.exe 4 true 1   -&gt; Uruchomienie programu testowego nr 1, bez predyktora, z 4 potokami</code></p>
<p>W sprawozdaniu:</p>
<ul>
<li>Ile cykli wykonywał się każdy program?</li>
<li>Dlaczego wystąpił pierwszy stall w każdym z programów?</li>
</ul>
<p>Kolejno należy zmieniać ilość dostępnych potoków, od 1 do 5. Proszę opisać jak zmieniał się czas wykonania (ilość cykli). Z czego to może wynikać.</p>
<p>Proszę wypisać wystapienia komunikatu: Instruction under this address can generate branch. Z czego wynika ten komunikat?</p>
<p><strong>Instruction reordering</strong></p>
<p>Proszę uruchomić program, opisać w sprawozdaniu jego wynik. Z czego wynika takie działanie programu? Należy przerwać wykonywanie zaraz po pojawieniu się pierwszych wyników.</p>
<p><code>$lab_10.exe</code></p>
<p><strong>Lab_11 - Lab_12 - Lab_13</strong></p>
<ol>
<li>Proszę uruchomić kolejno lab_11, lab_12, lab_13</li>
<li>W sprawozdaniu proszę umieścić wynik działania programów</li>
<li>Proszę zinterpretować wyniki.</li>
</ol>
<p>Lab_11  - program sekwencyjny
Lab_12a - podobny problem do lab_11, ale wielowątkowo
Lab_12b - podobny problem do lab_11, ale wielowątkowo, z rozwiązaniem problemu
Lab_13  - symulacja technologii HT</p>
<p><strong>Lab_15</strong></p>
<p>W poniższym programie przetestujemy dwa różne sposoby dostępu do pamięci: sekwencyjny i losowy. Porównamy czas wykonania obu podejść, które mogą wpływać na wykorzystanie pamięci cache.</p>
<p>Proszę uruchomić program, opisać w sprawozdaniu jego wynik.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$lab_15.exe &lt;iterations&gt; &lt;seq/random&gt;
</span></span><span class="line"><span class="cl">              &lt;50-1000&gt;    &lt;seq/random&gt;
</span></span></code></pre></td></tr></table>
</div>
</div><p>Należy modyfikować ilość iteracji: 50 75 100, uruchamiając dla dostępu sekwencyjnego i losowego.</p>
<p><strong>Lab_17</strong></p>
<p>Proszę uruchomić program, opisać w sprawozdaniu jego wynik. Należy kilka razy zmodyfikować parametry:</p>
<ul>
<li><code>-c 1024 -b 32 -n 10000 -m 2048</code></li>
<li><code>-c 1024 -b 64 -n 10000 -m 2048</code></li>
<li><code>-c 2048 -b 32 -n 10000 -m 4096</code></li>
<li><code>-c 2048 -b 64 -n 10000 -m 4096</code></li>
<li>inna konfiguracja wg uznania z taką samą liczbą iteracji</li>
<li>inna konfiguracja wg uznania z taką samą liczbą iteracji</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$lab_17.exe -c 1024 -b 32 -n 10000 -m 1024
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  -c, --cache size
</span></span><span class="line"><span class="cl">  -b, --block size
</span></span><span class="line"><span class="cl">  -n, --iteration
</span></span><span class="line"><span class="cl">  -m, --memory size
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>Lab_18</strong> - Prefetch</p>
<p>Proszę uruchomić program, opisać w sprawozdaniu jego wynik. Należy kilka razy zmodyfikować parametry:</p>
<ul>
<li><code>-c 1024 -b 32 -n 10000 -m 2048 -d 1</code></li>
<li><code>-c 1024 -b 64 -n 10000 -m 2048 -d 2</code></li>
<li><code>-c 2048 -b 32 -n 10000 -m 4096 -d 4</code></li>
<li><code>-c 2048 -b 64 -n 10000 -m 4096 -d 8</code></li>
<li>inna konfiguracja wg uznania z taką samą liczbą iteracji</li>
<li>inna konfiguracja wg uznania z taką samą liczbą iteracji</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$lab_18.exe -c 1024 -b 32 -n 10000 -m 1024 -d 8
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  -c, --cache size
</span></span><span class="line"><span class="cl">  -b, --block size
</span></span><span class="line"><span class="cl">  -n, --iteration
</span></span><span class="line"><span class="cl">  -m, --memory size
</span></span><span class="line"><span class="cl">  -d, --prefetch distance
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>Scenariusz problemu (architektura jednordzeniowa/wielordzeniowa)</strong></p>
<p>Przyjmijmy, że chcemy obliczyć wartości silni dla dużego zestawu liczb. Obliczenia te mają być wykonane sekwencyjnie dla każdej liczby w zestawie. Wartości silni obliczane są za pomocą iteracyjnej funkcji silni.</p>
<p>Porównanie rozwiązań na procesorze jedno- i wielordzeniowym:</p>
<ol>
<li>Procesor jednordzeniowy:</li>
</ol>
<p>&lt; Jak mogą wyglądać obliczenia? Jak mogą być przydzielane zasoby procesora? Wątki?&gt;</p>
<h2 id="zalety">Zalety:</h2>
<ul>
<li></li>
</ul>
<h2 id="wady">Wady:</h2>
<ul>
<li></li>
</ul>
<ol start="2">
<li>Procesor wielordzeniowy:</li>
</ol>
<p>&lt; Jak mogą wyglądać obliczenia? Jak mogą być przydzielane zasoby procesora? &gt;</p>
<h2 id="zalety-1">Zalety:</h2>
<ul>
<li></li>
</ul>
<h2 id="wady-1">Wady:</h2>
<ul>
<li></li>
</ul>
<p>Porównanie:</p>
<p>Które rozwiązanie będzie wydajniejsze i w jakim wypadku?
W jakich sytuacjach jedno rozwiązanie jest wydajniejsze od drugiego?</p>
]]></content:encoded></item><item><title>Architektura komputerów - Lab</title><link>https://marcinklimek.github.io/student/2023-arch/2023-05-28-architektura-komp-lab/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://marcinklimek.github.io/student/2023-arch/2023-05-28-architektura-komp-lab/</guid><description>&lt;!---
``` {=html}
&lt;style>
body { min-width: 80% !important; }
&lt;/style>
```
https://www.geeksforgeeks.org/computer-organization-and-architecture-tutorials/
-->
&lt;h1 id="treści-programowe">Treści programowe&lt;/h1>
&lt;h2 id="wykłady">Wykłady&lt;/h2>
&lt;ol>
&lt;li>Podstawowe typy architektur i pojęcia z nimi związane.&lt;/li>
&lt;li>Problemy w implementacji architektury potokowej i superskalarnej; metody ich rozwiązywania i wynikające z nich podukłady mikroprocesorów.&lt;/li>
&lt;li>Charakterystyka architektury wybranych współczesnych procesorów wykorzystywanych w urządzeniach stacjonarnych, mobilnych oraz superkomputerach.&lt;/li>
&lt;li>Komunikacja pomiędzy procesorem, pamięcią a urządzeniami wejścia/wyjścia.&lt;/li>
&lt;li>Charakterystyka architektury wybranych komputerów stacjonarnych oraz urządzeń mobilnych.&lt;/li>
&lt;li>Współczesne pamięci operacyjne / podstawowe parametry statyczne i dynamiczne.&lt;/li>
&lt;li>Typy magistral i ich parametry.&lt;/li>
&lt;li>Benchmarki.&lt;/li>
&lt;li>Charakterystyka mikrokomputerów jednoukładowych i ich przeznaczenie.&lt;/li>
&lt;/ol>
&lt;h2 id="ćwiczenia">Ćwiczenia&lt;/h2>
&lt;ol>
&lt;li>
&lt;p>Analiza szybkości wykonywania operacji stało- i zmiennoprzecinkowych.&lt;/p></description><content:encoded><![CDATA[<!---
``` {=html}
<style>
body { min-width: 80% !important; }
</style>
```

https://www.geeksforgeeks.org/computer-organization-and-architecture-tutorials/
-->
<h1 id="treści-programowe">Treści programowe</h1>
<h2 id="wykłady">Wykłady</h2>
<ol>
<li>Podstawowe typy architektur i pojęcia z nimi związane.</li>
<li>Problemy w implementacji architektury potokowej i superskalarnej; metody ich rozwiązywania i wynikające z nich podukłady mikroprocesorów.</li>
<li>Charakterystyka architektury wybranych współczesnych procesorów wykorzystywanych w urządzeniach stacjonarnych, mobilnych oraz superkomputerach.</li>
<li>Komunikacja pomiędzy procesorem, pamięcią a urządzeniami wejścia/wyjścia.</li>
<li>Charakterystyka architektury wybranych komputerów stacjonarnych oraz urządzeń mobilnych.</li>
<li>Współczesne pamięci operacyjne / podstawowe parametry statyczne i dynamiczne.</li>
<li>Typy magistral i ich parametry.</li>
<li>Benchmarki.</li>
<li>Charakterystyka mikrokomputerów jednoukładowych i ich przeznaczenie.</li>
</ol>
<h2 id="ćwiczenia">Ćwiczenia</h2>
<ol>
<li>
<p>Analiza szybkości wykonywania operacji stało- i zmiennoprzecinkowych.</p>
</li>
<li>
<p>Analiza cyklu rozkazowego i potoku rozkazowego w jednym rdzeniu procesora jedno i wielordzeniowego.</p>
</li>
<li>
<p>Komunikacja z pamięcią oraz z urządzeniami wejścia/wyjścia oraz obsługa przerwań.</p>
</li>
<li>
<p>Analiza działania wybranych instrukcji i przykładowych programów w asemblerze wybranego procesora.</p>
</li>
<li>
<p>Tworzenie przykładowych programów w asemblerze z wykorzystaniem instrukcji warunkowych i pętli.</p>
</li>
<li>
<p>Oprogramowanie układu sterującego dla przykładowego zadania (np. sterowanie światłami na
skrzyżowaniu, obsługą żądań przywołania windy itp.).</p>
</li>
</ol>
<h1 id="organizacja">Organizacja</h1>
<ol>
<li>Jeśli ktoś jest zainteresowany, proponuję włączyć kamerę - na tej podstawie sprawdzam obecność</li>
<li>Aktywność generuje plusy</li>
<li>Wyniki, rezultaty z ćwiczeń proszę wklejać na czat</li>
<li>Zaliczenie przedmiotu - kolokwium lub projekt
<ol>
<li>Jeśli kolokwium to odbędzie się na przedostatnich zajęciach (zakres ściśle powiązany ze skryptem)</li>
<li>Jeśli projekt, to prezentacja na ostatnich zajęciach - najprawdopodobniej stworzenie symulatora, powiązanego z tematyką zajęć.</li>
</ol>
</li>
<li>Zajęcia mają formułę warsztatów
<ol>
<li>Trochę omawiamy temat</li>
<li>Przeklejamy przykładowe programy lub programujemy je</li>
</ol>
</li>
<li>W dowolnym momencie proszę pytać o cokolwiek co jest związane z tematyką zajęć</li>
</ol>
<h1 id="wstęp">Wstęp</h1>
<p>Kilka problemów związanych z architekturą procesora i organizacją systemu komputerowego:</p>
<ol>
<li>
<p>Reordering instrukcji: Procesory mogą zmieniać kolejność wykonywania instrukcji, aby zoptymalizować wydajność. Może to prowadzić do problemów związanych z synchronizacją wątków i niezdefiniowanym zachowaniem. Aby temu zapobiec, można użyć odpowiednich metod synchronizacji, takich jak muteksy, blokady czy bariery pamięci.</p>
</li>
<li>
<p>Efekty związane z pamięcią cache: Dostęp do pamięci ma istotny wpływ na wydajność programu. Wysokiej wydajności algorytmy powinny być zaprojektowane z uwzględnieniem hierarchii pamięci, tak aby minimalizować opóźnienia związane z odwołaniami do pamięci. Można to osiągnąć, stosując techniki optymalizacji, takie jak blokowanie, użycie pamięci lokalnej czy cache-oblivious algorithms.</p>
</li>
<li>
<p>Równoczesność i współbieżność: Wykorzystanie wielowątkowości i wielordzeniowości procesorów może prowadzić do problemów związanych z dostępem do wspólnych zasobów, takich jak dane czy urządzenia wejścia/wyjścia. Aby zapewnić poprawną współpracę wątków, można stosować mechanizmy synchronizacji (muteksy, semafory, blokady) oraz techniki programowania równoległego, takie jak zadania, przetwarzanie równoległe czy potoki.</p>
</li>
<li>
<p>Wydajność arytmetyki zmiennoprzecinkowej: Obliczenia zmiennoprzecinkowe różnią się wydajnością w zależności od architektury procesora. Aby uzyskać najlepszą wydajność, można stosować optymalizacje specyficzne dla danego procesora, takie jak wektoryzacja, instrukcje SIMD czy optymalizacja obliczeń matematycznych.</p>
</li>
<li>
<p>Obsługa błędów sprzętowych: Błędy sprzętowe, takie jak błędy parzystości czy uszkodzenia pamięci, mogą wpłynąć na poprawność działania programu. Można zastosować techniki wykrywania i naprawy błędów, takie jak korekcja błędów pamięci czy sprawdzanie parzystości, aby zminimalizować ryzyko wprowadzenia błędów przez sprzęt.</p>
</li>
</ol>
<p>Aby uniknąć tych problemów i zapewnić poprawne działanie programu, ważne jest zapoznanie się z architekturą procesora, na którym ma być uruchomiony program, oraz zastosowanie odpowiednich technik programowania i optymalizacji. Oto kilka dodatkowych wskazówek:</p>
<ol start="6">
<li>
<p>Endianness: Kolejność bajtów w reprezentacji liczb wielobajtowych (little-endian lub big-endian) różni się między różnymi architekturami procesorów.</p>
</li>
<li>
<p>Wydajność operacji wejścia/wyjścia: Operacje wejścia/wyjścia mają znaczący wpływ na wydajność aplikacji. W przypadku programów wymagających intensywnego przepływu danych, należy zastosować techniki buforowania, asynchronicznych operacji wejścia/wyjścia oraz optymalizować użycie systemów plików i urządzeń wejścia/wyjścia.</p>
</li>
<li>
<p>Granice stronicowania: Dostęp do pamięci może być niejednorodny z powodu granic stronicowania. Aby uniknąć opóźnień związanych z przenoszeniem danych między stronami pamięci, można zastosować techniki takie jak wyrównywanie stronicowania (page alignment), stosowanie dużych stron (huge pages) czy ograniczenie fragmentacji pamięci.</p>
</li>
<li>
<p>Architektura NUMA (Non-Uniform Memory Access): W przypadku systemów wieloprocesorowych z architekturą NUMA, dostęp do pamięci może być wolniejszy dla niektórych rdzeni procesora. Aby zoptymalizować wydajność programów na takich systemach, można stosować techniki takie jak lokalność danych, afinitet rdzeni czy specjalne funkcje alokacji pamięci, takie jak <code>numa_alloc_onnode</code> i <code>numa_bind</code>.</p>
</li>
<li>
<p>Wsparcie dla instrukcji specyficznych dla procesora: Niektóre procesory mają instrukcje, które pozwalają na bardziej efektywne wykonanie określonych operacji. Można skorzystać z tych instrukcji, pisząc kod w asemblerze lub korzystając z bibliotek, które wykorzystują te instrukcje, takie jak biblioteki matematyczne czy algorytmiczne.</p>
</li>
</ol>
<p>Aby uniknąć problemów związanych z architekturą procesora i organizacją systemu komputerowego, ważne jest, aby programować z uwzględnieniem tych zagadnień. Dobrym podejściem jest też korzystanie z bibliotek i narzędzi, które już zostały zoptymalizowane pod kątem różnych architektur i systemów.</p>
<blockquote>
<p>Ref:</p>
<ul>
<li><a href="http://www.cs.ru.nl/lab/xenomai/exercises_xenomai2.4/ex10/Exercise-10.html">Measuring Jitter and Latency</a></li>
<li><a href="https://academo.org/demos/logic-gate-simulator/">logic gate simulator</a></li>
<li><a href="https://learn.microsoft.com/en-gb/windows/wsl/install-manual#step-2---check-requirements-for-running-wsl-2">WSL</a> !!</li>
<li>VirtualBox</li>
<li><a href="https://www.mingw-w64.org/">Mingw-w64</a></li>
<li><a href="https://agner.org/optimize/microarchitecture.pdf">The microarchitecture of Intel, AMD, and VIA CPUs</a></li>
</ul>
</blockquote>
<blockquote>
<ul>
<li>Architektura systoliczna - np. Edge TPU</li>
<li><a href="https://qengineering.eu/google-corals-tpu-explained.html">Google Coral Edge TPU explained in depth</a></li>
<li>Cell (PS3) - PowerPC (PPE) + 7 x „Synergistic Processing Elements” (SPEs) <a href="https://pl.wikipedia.org/wiki/PlayStation_3">PlayStation 3</a></li>
<li><a href="https://blog.inten.to/hardware-for-deep-learning-current-state-and-trends-51c01ebbb6dc">Hardware for Deep Learning</a></li>
<li><a href="https://tp4348.medium.com/multithreaded-programs-on-gpu-7ae4dfbb19d3">Unlocking the Secrets of GPU Architecture</a></li>
<li><a href="https://lobste.rs/s/okcml7/cpu_is_compiler">A CPU is a compiler</a></li>
</ul>
</blockquote>
<h1 id="reprezentacja-liczb">Reprezentacja liczb</h1>
<h3 id="system-dziesiętny">System dziesiętny</h3>
<p>Liczba 13910 jest zapisana w systemie dziesiętnym, co oznacza, że każda pozycja odpowiada potędze liczby 10. System pozycyjny to sposób zapisu liczb, w którym wartość liczby zależy od wartości cyfr i ich pozycji. W systemie wagowym wartość liczby jest sumą iloczynów cyfr i wag pozycji, gdzie wagi pozycji są potęgami podstawy systemu.</p>
<p>Liczba 13910 z rozbiciem na wagi poszczególnych pozycji:</p>
<pre><code>1 * 10^4 + 
3 * 10^3 + 
9 * 10^2 + 
1 * 10^1 + 
0 * 10^0 =

10000 + 3000 + 900 + 10 + 0 = 13910
</code></pre>
<h3 id="system-binarny">System binarny</h3>
<p>Konwersja liczby 13910 na zapis binarny:</p>
<pre><code>13910 : 2 = 6955 (reszta: 0)
6955  : 2 = 3477 (reszta: 1)
3477  : 2 = 1738 (reszta: 1)
1738  : 2 = 869  (reszta: 0)
869   : 2 = 434  (reszta: 1)
434   : 2 = 217  (reszta: 0)
217   : 2 = 108  (reszta: 1)
108   : 2 = 54   (reszta: 0)
54    : 2 = 27   (reszta: 0)
27    : 2 = 13   (reszta: 1)
13    : 2 = 6    (reszta: 1)
6     : 2 = 3    (reszta: 0)
3     : 2 = 1    (reszta: 1)
1     : 2 = 0    (reszta: 1)

Liczba binarna: 11 0110 0101 0110
</code></pre>
<p><strong>Ćwiczenie</strong></p>
<p>Zamienić na liczbę w notacji binarnej za pomocą powyższej metody:</p>
<ul>
<li>19</li>
<li>1977</li>
</ul>
<blockquote>
<p>Naturalny kod binarny to sposób zapisu liczb, w którym wartość liczby jest sumą iloczynów cyfr i wag pozycji, gdzie wagi pozycji są potęgami liczby 2.</p>
</blockquote>
<p>Liczba 1011 0101 z rozbiciem na wagi poszczególnych pozycji:</p>
<pre><code>1 * 2^7 + 
0 * 2^6 + 
1 * 2^5 + 
1 * 2^4 + 
0 * 2^3 + 
1 * 2^2 + 
0 * 2^1 + 
1 * 2^0 = 

128 + 32 + 16 + 4 + 1 = 181
</code></pre>
<h3 id="system-szesnastkowy">System szesnastkowy</h3>
<table>
  <thead>
      <tr>
          <th></th>
          <th></th>
          <th></th>
          <th></th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>0</td>
          <td>0000</td>
          <td>8</td>
          <td>1000</td>
      </tr>
      <tr>
          <td>1</td>
          <td>0001</td>
          <td>9</td>
          <td>1001</td>
      </tr>
      <tr>
          <td>2</td>
          <td>0010</td>
          <td>A</td>
          <td>1010</td>
      </tr>
      <tr>
          <td>3</td>
          <td>0011</td>
          <td>B</td>
          <td>1011</td>
      </tr>
      <tr>
          <td>4</td>
          <td>0100</td>
          <td>C</td>
          <td>1100</td>
      </tr>
      <tr>
          <td>5</td>
          <td>0101</td>
          <td>D</td>
          <td>1101</td>
      </tr>
      <tr>
          <td>6</td>
          <td>0110</td>
          <td>E</td>
          <td>1110</td>
      </tr>
      <tr>
          <td>7</td>
          <td>0111</td>
          <td>F</td>
          <td>1111</td>
      </tr>
  </tbody>
</table>
<p>Aby przekonwertować liczbę binarną 1011011100101101 na szesnastkowy, można ją podzielić na grupy po 4 bity i przypisać im wartości szesnastkowe:</p>
<pre><code>1011 0111 0010 1101
   B    7    2    D
</code></pre>
<p>Liczba szesnastkowa: B72D</p>
<h3 id="przechowywanie-danych-w-komputerach">Przechowywanie danych w komputerach</h3>
<p><strong>Narysować pamięć</strong></p>
<p>Dane w komputerze są przechowywane w postaci binarnej, czyli za pomocą bitów (0 i 1). System binarny został wybrany ze względu na prostotę realizacji elektronicznej (wysokie i niskie napięcie) oraz łatwość przetwarzania informacji.</p>
<p>Rejestr to mały obszar pamięci w procesorze, używany do przechowywania wartości, które są obecnie przetwarzane. Słowo to ciąg bitów, który odpowiada długości rejestru lub jednostki przetwarzania danych.</p>
<p>Załóżmy, że mamy rejestr 8-bitowy. Aby zapisać wartość 139 (10001011) w rejestrze, wystarczy ustawić bity na odpowiednie wartości:
10001011</p>
<p>Ile bitów jest potrzebnych na zapisanie liczby 139, 255, 269, 513?</p>
<pre><code>139: 8 bitów (10001011)
255: 8 bitów (11111111)
269: 9 bitów (100001101)
513: 10 bitów (1000000001)
</code></pre>
<p>Liczba potrzebnych bitów do zapisania każdej z tych liczb zależy od ich wartości w postaci binarnej. Aby określić minimalną ilość bitów potrzebną do zapisania danej liczby, można zastosować funkcję logarytmu dwójkowego (lub log2), a następnie zaokrąglić wynik w górę do najbliższej liczby całkowitej.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="n">math</span><span class="o">.</span><span class="n">ceil</span><span class="p">(</span> <span class="n">math</span><span class="o">.</span><span class="n">log2</span><span class="p">(</span><span class="mi">269</span><span class="p">)</span> <span class="p">)</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h3 id="co-to-jest-rejestr">Co to jest rejestr?</h3>
<h3 id="nadmiar-i-niedomiar">Nadmiar i niedomiar</h3>
<p><strong>Ćwiczenie</strong></p>
<ul>
<li>Czy wynik operacji mieści się w 8-bitowym rejestrze? (nadmiar czy niedomiar)</li>
<li>Ile bitów potrzeba do reprezentacji wyniku?</li>
</ul>
<ol>
<li>
<p>Dodawanie:</p>
<pre><code> A = 127 (01111111)
 B = 4 (00000100)
 A + B = 131 (10000011)
</code></pre>
</li>
<li>
<p>Dodawanie:</p>
<pre><code> A = 139 (10001011)
 B = 147 (10010011)
 A + B = 286 (1 00010010) 
 efekt nadmiaru, wynik nie mieści się w 8-bitowym rejestrze.
</code></pre>
</li>
</ol>
<p>W drugim przypadku mamy do czynienia z nadmiarem, co oznacza, że wynik przekracza maksymalną wartość, która może być przechowywana w 8-bitowym rejestrze (255).</p>
<ol start="3">
<li>
<p>Odejmowanie:</p>
<pre><code> A = 115 (01110011)
 B = 5 (00000101)
 C = A - B = 110 (01101110)
</code></pre>
</li>
<li>
<p>Odejmowanie:</p>
<pre><code> A = 129 (10000001)
 B = 167 (10100111)
 C = A - B = -38 (11011010)
 efekt niedomiaru, ponieważ wynik jest liczbą ujemną.
</code></pre>
</li>
</ol>
<h3 id="liczby-ujemne">Liczby ujemne</h3>
<ol>
<li>Z bitem znaku</li>
<li>U2</li>
</ol>
<p>Aby zapisać liczbę -2 w 8-bitowym rejestrze, używamy kodu U2 (Uzupełnienie do 2):</p>
<pre><code>-2 = 11111110
</code></pre>
<p>Przykład dla liczby 10110101:</p>
<ol>
<li>
<p>Jako liczba dodatnia:</p>
<pre><code> 1 * 2^7 + 
 0 * 2^6 + 
 1 * 2^5 + 
 1 * 2^4 + 
 0 * 2^3 + 
 1 * 2^2 + 
 0 * 2^1 + 
 1 * 2^0 = 

 128 + 32 + 16 + 4 + 1 = 181
</code></pre>
</li>
<li>
<p>Jako liczba ujemna (w kodzie U2):</p>
<pre><code>~1011 0101 + 1 = 
 0100 1010 + 1 = 0100 1011

 co daje: 64 + 8 + 2 + 1 = 75, 
 więc liczba to -75.
</code></pre>
</li>
</ol>
<blockquote>
<p>Interpretacja liczby zależy od kontekstu. W przypadku liczb ujemnych często stosowany jest kod U2.</p>
</blockquote>
<h4 id="kod-u2">Kod U2</h4>
<p>Uzupełnienie do 2, to metoda reprezentacji liczb całkowitych, zarówno dodatnich, jak i ujemnych, w systemie binarnym. W kodzie U2 liczby dodatnie są reprezentowane tak samo jak w naturalnym kodzie binarnym, natomiast liczby ujemne są reprezentowane jako dopełnienie do 2 liczby bezwzględnej.</p>
<p>Obliczanie reprezentację liczby ujemnej w kodzie U2:</p>
<ol>
<li>Przekształć wartość bezwzględną liczby ujemnej na postać binarną.</li>
<li>Odwróć bity (zmień 0 na 1 i 1 na 0).</li>
<li>Dodaj 1 do wyniku.</li>
</ol>
<p>Przykłady:</p>
<ol>
<li>
<p>Przykład dla liczby -3:</p>
<pre><code>1. Wartość bezwzględna: 3 (w binarnym: 0000 0011)
2. Odwrócenie bitów: 1111 1100
3. Dodanie 1: 1111 1100 + 1 = 1111 1101

Kod U2 dla liczby -3: 1111 1101
</code></pre>
</li>
<li>
<p>Przykład dla liczby -7:</p>
<pre><code>1. Wartość bezwzględna: 7 (w binarnym: 0000 0111)
2. Odwrócenie bitów: 1111 1000
3. Dodanie 1: 1111 1000 + 1 = 1111 1001

Kod U2 dla liczby -7: 1111 1001
</code></pre>
</li>
</ol>
<blockquote>
<p>Kod U2 jest często stosowany w komputerach, ponieważ pozwala na wykonywanie operacji dodawania i odejmowania przy użyciu tego samego sprzętu, niezależnie od znaku liczb.</p>
</blockquote>
<p><strong>Ćwiczenie</strong></p>
<ol>
<li>-7</li>
<li>-117</li>
</ol>
<h3 id="liczby-rzeczywiste">Liczby rzeczywiste</h3>
<pre><code>11 i 5/16 = 11.3125
</code></pre>
<p>Liczba 11 w postaci binarnej to 1011.</p>
<p>5/16 jako ułamek binarny to 0.0101 ponieważ</p>
<pre><code> 1 * (1/2)^3 + 
 0 * (1/2)^4 + 
 1 * (1/2)^5)

0.3125 * 2 = 0.625 -&gt; 0
0.625  * 2 = 1.25  -&gt; 1
0.25   * 2 = 0.5   -&gt; 0
0.5    * 2 = 1     -&gt; 1
</code></pre>
<p>Liczba 11 i 5/16 w postaci binarnej to: 1011.0101</p>
<p>Potrzebujemy 8 bitów na zapisanie tej liczby. Można zapisać ją w rejestrze jako liczba stałoprzecinkowa (zakładając, że przecinek jest zawsze pomiędzy bitami 3 i 4) lub używając notacji zmiennoprzecinkowej, która pozwala na zapisanie liczby z określoną precyzją i zakresem.</p>
<h4 id="zamiana-na-postać-binarną">Zamiana na postać binarną</h4>
<p>Aby przekształcić liczbę dziesiętną 10.75 na liczbę binarną, należy przekształcić osobno jej część całkowitą i część ułamkową.</p>
<ol>
<li>
<p>Konwersja części całkowitej:</p>
<pre><code> Liczba całkowita: 10
 Postępujemy według metody dzielenia przez 2:

 10 / 2 = 5, reszta: 0
  5 / 2 = 2, reszta: 1
  2 / 2 = 1, reszta: 0
  1 / 2 = 0, reszta: 1

 Czytamy reszty od dołu do góry: 1010
</code></pre>
</li>
<li>
<p>Konwersja części ułamkowej:</p>
<pre><code> Liczba ułamkowa: 0.75
 Postępujemy według metody mnożenia przez 2:
 0.75 * 2 = 1.5 (zapisujemy cyfrę 1)
 0.50 * 2 = 1.0 (zapisujemy cyfrę 1)

 Czytam od góry do dołu: 11
</code></pre>
</li>
</ol>
<p>Teraz, aby uzyskać postać binarną liczby 10.75, łączymy część całkowitą (1010) i część ułamkową (11) za pomocą przecinka binarnego: 1010.11</p>
<p>Stąd wynika, że liczba dziesiętna 10.75 jest równa liczbie binarnej 1010.11</p>
<blockquote>
<p>Uwaga
Podczas konwersji liczby ułamkowej dziesiętnej na liczbę binarną za pomocą metody mnożenia przez 2, należy zakończyć mnożenie w jednym z następujących przypadków:</p>
<ol>
<li>
<p>Gdy wartość ułamkowa po mnożeniu wynosi dokładnie 0. Wtedy wszystkie kolejne mnożenia również będą dawały 0, a kolejne cyfry binarne po przecinku będą się składały wyłącznie z zer. W takiej sytuacji nie &gt; ma potrzeby kontynuować obliczeń.</p>
</li>
<li>
<p>Gdy osiągniesz żądaną precyzję. W praktyce, liczby binarne używane w komputerach mają ograniczoną precyzję (np. w przypadku liczb zmiennoprzecinkowych w standardzie IEEE-754). W związku z tym możemy &gt; zakończyć mnożenie po osiągnięciu określonej liczby cyfr binarnych po przecinku.</p>
</li>
<li>
<p>Gdy zauważysz cykliczne powtarzanie się wzoru cyfr. W niektórych przypadkach, liczby ułamkowe dziesiętne mają nieskończoną reprezentację binarną, która powtarza się cyklicznie. Kiedy zauważysz taki wzór, &gt; możesz zakończyć mnożenie i zaokrąglić wynik do żądanej precyzji.</p>
</li>
</ol>
<p>Należy pamiętać, że niektóre liczby ułamkowe dziesiętne mają nieskończoną reprezentację binarną, która nie wykazuje cyklicznego powtarzania się wzoru. W takich przypadkach, można zakończyć mnożenie, gdy &gt; osiągnięta zostanie żądana precyzja, biorąc pod uwagę ograniczenia sprzętowe lub wymagania dotyczące zaokrąglenia.</p>
</blockquote>
<h4 id="przykłady">Przykłady</h4>
<ol>
<li>
<p>Liczba dziesiętna 0.5:</p>
<pre><code> 0.5 * 2 = 1.0 (zapisujemy cyfrę 1)
 Binarnie: 0.1
</code></pre>
</li>
<li>
<p>Liczba dziesiętna 0.25:</p>
<pre><code> 0.25 * 2 = 0.5 (zapisujemy cyfrę 0)
 0.5 * 2 = 1.0 (zapisujemy cyfrę 1)
 Binarnie: 0.01
</code></pre>
</li>
<li>
<p>Liczba dziesiętna 0.625:</p>
<pre><code> 0.625 * 2 = 1.25 (zapisujemy cyfrę 1)
 0.25 * 2 = 0.5 (zapisujemy cyfrę 0)
 0.5 * 2 = 1.0 (zapisujemy cyfrę 1)
 Binarnie: 0.101
</code></pre>
</li>
<li>
<p>Liczba dziesiętna 0.375:</p>
<pre><code> 0.375 * 2 = 0.75 (zapisujemy cyfrę 0)
 0.75 * 2 = 1.5 (zapisujemy cyfrę 1)
 0.5 * 2 = 1.0 (zapisujemy cyfrę 1)
 Binarnie: 0.011
</code></pre>
</li>
<li>
<p>Liczba dziesiętna 0.1977:</p>
<pre><code> 0.1977 * 2 = 0.3954 -&gt; (0.0)
 0.3954 * 2 = 0.7908 -&gt; (0.00)
 0.7908 * 2 = 1.5816 -&gt; (0.001)
 0.5816 * 2 = 1.1632 -&gt; (0.0011)
 0.1632 * 2 = 0.3264 -&gt; (0.00110)
 0.3264 * 2 = 0.6528 -&gt; (0.001100)
 0.6528 * 2 = 1.3056 -&gt; (0.0011001)
</code></pre>
</li>
</ol>
<blockquote>
<p>Warto zauważyć, że niektóre liczby ułamkowe w systemie dziesiętnym nie mają dokładnej reprezentacji w systemie binarnym.</p>
</blockquote>
<ol start="6">
<li>
<p>Liczba dziesiętna 0.1:</p>
<pre><code> 0.1 * 2 = 0.2 (zapisujemy cyfrę 0)
 0.2 * 2 = 0.4 (zapisujemy cyfrę 0)
 0.4 * 2 = 0.8 (zapisujemy cyfrę 0)
 0.8 * 2 = 1.6 (zapisujemy cyfrę 1)
 0.6 * 2 = 1.2 (zapisujemy cyfrę 1)
 0.2 * 2 = 0.4 (zapisujemy cyfrę 0)
 ...
 Binarnie: 0.0001100110011... (cyfry się powtarzają)
</code></pre>
</li>
</ol>
<p>W takich przypadkach reprezentacja binarna będzie nieskończoną liczbą cyfr po przecinku i musi zostać zaokrąglona, aby zmieścić się w określonym formacie, takim jak standard IEEE-754.</p>
<h4 id="notacja-zmiennoprzecinkowa">Notacja zmiennoprzecinkowa</h4>
<p>W komputerach najczęściej stosowaną notacją zmiennoprzecinkową jest standard IEEE-754. Standard ten definiuje formaty reprezentacji liczb zmiennoprzecinkowych, takie jak pojedyncza precyzja (32 bity) i podwójna precyzja (64 bity). Standard IEEE-754 pozwala na zapisanie liczb z określoną precyzją, zakresem i specjalnymi wartościami (takimi jak nieskończoność i NaN). Na niektórych platformach dostępny jest typ half-float (NVidia CUDA) o połowicznej precyzji (16 bitów)</p>
<p>Reprezentacja liczby zmiennoprzecinkowej w standardzie IEEE-754 składa się z trzech części:</p>
<ol>
<li>Znak (Sign) - jeden bit, który reprezentuje znak liczby (0 - dodatnia, 1 - ujemna).</li>
<li>Wykładnik (Exponent) - ciąg bitów reprezentujący wykładnik liczby, przesunięty o wartość stałą (bias). Dla formatu pojedynczej precyzji przesunięcie wynosi 127, a dla podwójnej precyzji wynosi 1023.</li>
<li>Mantysa (Significand) - ciąg bitów reprezentujący wartość liczby znormalizowanej, ale bez pierwszego bitu (1), który jest zawsze niejawny (chyba że liczba jest denormalizowana).</li>
</ol>
<p><img loading="lazy" src="/images/IEEE754.png" type="" alt="IEEE-754"  /></p>
<p>Tworzenie reprezentacji binarnej liczby zmiennoprzecinkowej w standardzie IEEE-754:</p>
<ol>
<li>Określ znak liczby (0 dla dodatniej, 1 dla ujemnej).</li>
<li>Zamienić część dziesiętną oraz ułamkową na postać binarną.</li>
<li>Przekształć liczbę na postać znormalizowaną w notacji naukowej (1.x * 2^n).</li>
<li>Oblicz wykładnik, dodając przesunięcie (bias) do n (wykładnik notacji naukowej).</li>
<li>Przekształć mantysę na postać binarną, pomijając pierwszy bit (1).</li>
<li>Złożyć reprezentację z części znakowej, wykładnika i mantysy.</li>
</ol>
<p>Przykład:</p>
<p>Chcemy zapisać liczbę 10.75 jako liczbę zmiennoprzecinkową w standardzie IEEE-754 (pojedyncza precyzja).</p>
<ol>
<li>Liczba jest dodatnia, więc znak to 0.</li>
<li>Postać binarną: 10.75 = 1010.11</li>
<li>Postać znormalizowana: 1.01011 * 2^3</li>
<li>Wykładnik: 3 + 127 (bias) = 130, w postaci binarnej: 10000010</li>
<li>Mantysa (bez pierwszego bitu): 0101100&hellip; (w sumie 23 bity)</li>
<li>Składamy reprezentację: 0 10000010 01011000000000000000000</li>
</ol>
<p>Reprezentacja liczby 10.75 w standardzie IEEE-754 (pojedyncza precyzja) to:</p>
<pre><code>32 31 30 29 28 27 26 25 24 23 22 21 20 19 18 17 16 15 14 13 12 11 10 9  8  7  6  5  4  3  2  1
0  1  0  0  0  0  0  1  0  0  1  0  1  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0

1 * 2^3 * 1.34375 = 10.75
</code></pre>
<blockquote>
<p>Ref:</p>
<ul>
<li><a href="http://www.cburch.com/books/float/">http://www.cburch.com/books/float/</a></li>
<li><a href="http://evanw.github.io/float-toy/">Float Toy</a></li>
<li><a href="https://docs.oracle.com/cd/E19957-01/800-7895/800-7895.pdf">What Every Computer Scientist Should Know About Floating-Point Arithmetic</a></li>
</ul>
</blockquote>
<h1 id="kolejność-bajtów">Kolejność bajtów</h1>
<p>Przykład reprezentacji liczby 32-bitowej (4-bajtowej) w różnych kolejnościach bajtów:</p>
<p>Wartość: 0x12345678</p>
<ul>
<li>Little-endian: 78 56 34 12</li>
<li>Big-endian: 12 34 56 78</li>
</ul>
<p>Poniżej znajduje się przykładowy program w C++, który demonstruje różne kolejności bajtów:</p>
<p><strong>Lab_01:</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;cstdint&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">union</span> <span class="nc">EndianTest</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint32_t</span> <span class="n">i</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">uint8_t</span> <span class="n">c</span><span class="p">[</span><span class="mi">4</span><span class="p">];</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">EndianTest</span> <span class="n">test</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">test</span><span class="p">.</span><span class="n">i</span> <span class="o">=</span> <span class="mh">0x12345678</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;System ma następującą kolejność bajtów: &#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="n">test</span><span class="p">.</span><span class="n">c</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0x78</span> <span class="o">&amp;&amp;</span> <span class="n">test</span><span class="p">.</span><span class="n">c</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0x56</span> <span class="o">&amp;&amp;</span> <span class="n">test</span><span class="p">.</span><span class="n">c</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0x34</span> <span class="o">&amp;&amp;</span> <span class="n">test</span><span class="p">.</span><span class="n">c</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0x12</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Little-endian&#34;</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">test</span><span class="p">.</span><span class="n">c</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0x12</span> <span class="o">&amp;&amp;</span> <span class="n">test</span><span class="p">.</span><span class="n">c</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0x34</span> <span class="o">&amp;&amp;</span> <span class="n">test</span><span class="p">.</span><span class="n">c</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0x56</span> <span class="o">&amp;&amp;</span> <span class="n">test</span><span class="p">.</span><span class="n">c</span><span class="p">[</span><span class="mi">3</span><span class="p">]</span> <span class="o">==</span> <span class="mh">0x78</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Big-endian&#34;</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Nieznana&#34;</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Różne procesory używają różnych kolejności bajtów:</p>
<ul>
<li>Little-endian: Procesory Intel x86, x86-64 oraz większość mikrokontrolerów ARM (w trybie little-endian).</li>
<li>Big-endian: Procesory Motorola 68k, PowerPC, IBM z/Architecture, a także niektóre mikrokontrolery ARM (w trybie big-endian).</li>
</ul>
<p>Wybór kolejności bajtów jest często wynikiem decyzji projektowych, które miały na celu ułatwienie lub optymalizację wykonywania określonych operacji. Little-endian jest popularne ze względu na prostotę dodawania i odejmowania liczb o zmiennej długości oraz łatwiejszą obsługę liczb o mniejszej precyzji w reprezentacji o większej precyzji. Big-endian jest częściej stosowany w systemach, które muszą współpracować z sieciami komputerowymi, gdzie bajty są przesyłane od najbardziej znaczącego do najmniej znaczącego, co ułatwia interpretację wartości przesyłanych danych.</p>
<blockquote>
<p>Ref:</p>
<ul>
<li><a href="https://blog.fabrykowski.pl/little-endian.html">Jak to jest z tym little-endian</a></li>
</ul>
</blockquote>
<h1 id="wykonywania-operacji-stało--i-zmiennoprzecinkowych">Wykonywania operacji stało- i zmiennoprzecinkowych:</h1>
<p>FPU (Floating Point Unit) to podzespoły procesora odpowiedzialne za wykonywanie operacji arytmetycznych na liczbach zmiennoprzecinkowych. Liczba jednostek FPU może się różnić w zależności od architektury i modelu procesora. Oto kilka przykładów:</p>
<ol>
<li>Intel Core i7-8700K (8. generacja Core)</li>
</ol>
<ul>
<li>6 rdzeni, każdy z jednostką FPU - 6 jednostek FPU.</li>
</ul>
<ol start="2">
<li>AMD Ryzen 7 3700X (3. generacja Ryzen)</li>
</ol>
<ul>
<li>8 rdzeni, każdy z jednostką FPU - 8 jednostek FPU.</li>
</ul>
<ol start="3">
<li>Apple M1 (ARM-based)</li>
</ol>
<ul>
<li>8 rdzeni CPU (4 wysokiej wydajności i 4 energooszczędne), każdy z jednostką FPU - 8 jednostek FPU.</li>
</ul>
<ol start="4">
<li>IBM POWER9</li>
</ol>
<ul>
<li>12 lub 24 rdzenie, w zależności od konfiguracji. Każdy rdzeń ma jedną jednostkę FPU - 12 lub 24 jednostki FPU.</li>
</ul>
<ol start="5">
<li>NVIDIA A100 (GPU)</li>
</ol>
<ul>
<li>W przypadku GPU, jednostki FPU są zintegrowane z procesorami strumieniowymi (CUDA cores). NVIDIA A100 posiada 6912 rdzeni CUDA.</li>
</ul>
<p>Warto zauważyć, że w przypadku GPU, jednostki FPU mogą być wykorzystywane do obliczeń równoległych, ale zwykle nie są one traktowane jako oddzielne jednostki, tak jak w przypadku CPU.</p>
<h2 id="porównanie-czasu-wykonywania">Porównanie czasu wykonywania</h2>
<p>Porównanie czasu wykonywania dodawania, odejmowania, mnożenia i dzielenia dla liczby stałoprzecinkowej (int) i zmiennoprzecinkowej (float, double).</p>
<ol>
<li>Utwórz program, który generuje losowe liczby int oraz float (lub double) i wykonuje podstawowe operacje matematyczne.</li>
<li>Zmierz czas wykonania każdej operacji dla różnych precyzji.</li>
<li>Porównaj wyniki i zastanów się nad wpływem precyzji na czas wykonania operacji.</li>
</ol>
<p><strong>Lab_02:</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span><span class="lnt">65
</span><span class="lnt">66
</span><span class="lnt">67
</span><span class="lnt">68
</span><span class="lnt">69
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;iomanip&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;chrono&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;random&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="p">,</span><span class="n">std</span><span class="o">::</span><span class="n">enable_if_t</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">is_integral</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;::</span><span class="n">value</span><span class="p">,</span> <span class="kt">bool</span><span class="o">&gt;</span> <span class="o">=</span><span class="nb">true</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="n">T</span> <span class="n">generateRandomNumber</span><span class="p">(</span><span class="n">T</span> <span class="n">min</span><span class="p">,</span> <span class="n">T</span> <span class="n">max</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">static</span> <span class="n">random_device</span> <span class="n">rd</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">static</span> <span class="n">mt19937</span> <span class="nf">gen</span><span class="p">(</span><span class="n">rd</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">    <span class="n">uniform_int_distribution</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">dist</span><span class="p">(</span><span class="n">min</span><span class="p">,</span> <span class="n">max</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nf">dist</span><span class="p">(</span><span class="n">gen</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="p">,</span><span class="n">std</span><span class="o">::</span><span class="n">enable_if_t</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">is_floating_point</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;::</span><span class="n">value</span><span class="p">,</span> <span class="kt">bool</span><span class="o">&gt;</span> <span class="o">=</span> <span class="nb">true</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="n">T</span> <span class="n">generateRandomNumber</span><span class="p">(</span><span class="n">T</span> <span class="n">min</span><span class="p">,</span> <span class="n">T</span> <span class="n">max</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">static</span> <span class="n">random_device</span> <span class="n">rd</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">static</span> <span class="n">mt19937</span> <span class="nf">gen</span><span class="p">(</span><span class="n">rd</span><span class="p">());</span>
</span></span><span class="line"><span class="cl">    <span class="n">uniform_real_distribution</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">dist</span><span class="p">(</span><span class="n">min</span><span class="p">,</span> <span class="n">max</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nf">dist</span><span class="p">(</span><span class="n">gen</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="n">T</span> <span class="n">complex_operation</span><span class="p">(</span><span class="n">T</span> <span class="n">a</span><span class="p">,</span> <span class="n">T</span> <span class="n">b</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">T</span> <span class="n">result</span> <span class="o">=</span> <span class="p">(</span><span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="n">a</span> <span class="o">-</span> <span class="n">b</span><span class="p">)</span> <span class="o">/</span> <span class="p">(</span><span class="n">a</span> <span class="o">*</span> <span class="n">b</span><span class="p">);</span> <span class="c1">// +std::sin(a) - std::cos(b);
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">return</span> <span class="n">result</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">perform_operations</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">data_type</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">const</span> <span class="k">auto</span> <span class="n">num_operations</span> <span class="o">=</span> <span class="mi">10LL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">a</span><span class="p">(</span><span class="n">num_operations</span><span class="p">),</span> <span class="n">b</span><span class="p">(</span><span class="n">num_operations</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">num_operations</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> 
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">generateRandomNumber</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1000</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">        <span class="n">b</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">generateRandomNumber</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="mi">1000</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">T</span> <span class="n">result</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">auto</span> <span class="n">start</span> <span class="o">=</span> <span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">now</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">num_operations</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> 
</span></span><span class="line"><span class="cl">        <span class="n">result</span> <span class="o">+=</span> <span class="n">complex_operation</span><span class="p">(</span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">],</span> <span class="n">b</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">const</span> <span class="k">auto</span> <span class="n">end</span> <span class="o">=</span> <span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">now</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="k">const</span> <span class="n">duration</span><span class="o">&lt;</span><span class="kt">double</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">milli</span><span class="o">&gt;</span> <span class="n">elapsed</span> <span class="o">=</span> <span class="n">end</span> <span class="o">-</span> <span class="n">start</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Time taken for &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">data_type</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;: &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">elapsed</span><span class="p">.</span><span class="n">count</span><span class="p">()</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; ms&#34;</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">result</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">perform_operations</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="s">&#34;int&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">perform_operations</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span><span class="p">(</span><span class="s">&#34;float&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">perform_operations</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">&gt;</span><span class="p">(</span><span class="s">&#34;double&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Ten program w C++ analizuje wpływ precyzji zmiennoprzecinkowej na czas wykonania operacji. Wykonuje on podstawowe operacje matematyczne (<code>+</code>, <code>-</code>, <code>*</code>, <code>/</code>) na liczbach <code>całkowitych</code>oraz zmiennoprzecinkowych o różnych precyzjach (<code>float</code>, <code>double</code>) i mierzy czas wykonania tych operacji za pomocą biblioteki <code>&lt;chrono&gt;</code>.</p>
<p>Po skompilowaniu i uruchomieniu programu, na konsoli zostaną wyświetlone wyniki czasu wykonania operacji dla różnych precyzji. Należy przeanalizować wyniki i zastanowić się nad wpływem precyzji na czas wykonania operacji.</p>
<h2 id="obliczanie-czasu-wykonywania-operacji-na-macierzach-stało--i-zmiennoprzecinkowych">Obliczanie czasu wykonywania operacji na macierzach stało- i zmiennoprzecinkowych.</h2>
<ol>
<li>Napisz program, który mnoży dwie macierze o ustalonych rozmiarach, używając typów stałoprzecinkowych (int) oraz zmiennoprzecinkowych (float, double).</li>
<li>Zmierz czas wykonania mnożenia macierzy dla różnych rozmiarów macierzy.</li>
<li>Porównaj wyniki i omów znaczenie różnic w czasie wykonania dla różnych typów danych.</li>
</ol>
<p><strong>Lab_04:</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;chrono&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">multiply_matrices</span><span class="p">(</span><span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span> <span class="o">&amp;</span><span class="n">matrix1</span><span class="p">,</span> <span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span> <span class="o">&amp;</span><span class="n">matrix2</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span> <span class="o">&amp;</span><span class="n">result</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">size_t</span> <span class="n">rows</span> <span class="o">=</span> <span class="n">matrix1</span><span class="p">.</span><span class="n">size</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="n">size_t</span> <span class="n">cols</span> <span class="o">=</span> <span class="n">matrix2</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">size</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="n">size_t</span> <span class="n">inner</span> <span class="o">=</span> <span class="n">matrix1</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="n">size</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="n">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">rows</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="p">(</span><span class="n">size_t</span> <span class="n">j</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">j</span> <span class="o">&lt;</span> <span class="n">cols</span><span class="p">;</span> <span class="o">++</span><span class="n">j</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">result</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">for</span> <span class="p">(</span><span class="n">size_t</span> <span class="n">k</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">k</span> <span class="o">&lt;</span> <span class="n">inner</span><span class="p">;</span> <span class="o">++</span><span class="n">k</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">result</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">]</span> <span class="o">+=</span> <span class="n">matrix1</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">k</span><span class="p">]</span> <span class="o">*</span> <span class="n">matrix2</span><span class="p">[</span><span class="n">k</span><span class="p">][</span><span class="n">j</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">test_matrix_multiplication</span><span class="p">(</span><span class="kt">int</span> <span class="n">size</span><span class="p">,</span> <span class="k">const</span> <span class="n">string</span> <span class="o">&amp;</span><span class="n">type_name</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Inicjalizacja macierzy
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span> <span class="n">matrix1</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">2</span><span class="p">)));</span>
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span> <span class="n">matrix2</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">3</span><span class="p">)));</span>
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;&gt;</span> <span class="n">result</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="n">size</span><span class="p">,</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">0</span><span class="p">)));</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// Mierzenie czasu mnożenia macierzy
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">auto</span> <span class="n">start_time</span> <span class="o">=</span> <span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">now</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="n">multiply_matrices</span><span class="p">(</span><span class="n">matrix1</span><span class="p">,</span> <span class="n">matrix2</span><span class="p">,</span> <span class="n">result</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">auto</span> <span class="n">end_time</span> <span class="o">=</span> <span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">now</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">auto</span> <span class="n">duration</span> <span class="o">=</span> <span class="n">duration_cast</span><span class="o">&lt;</span><span class="n">milliseconds</span><span class="o">&gt;</span><span class="p">(</span><span class="n">end_time</span> <span class="o">-</span> <span class="n">start_time</span><span class="p">).</span><span class="n">count</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Czas wykonania mnożenia macierzy &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">size</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;x&#34;</span> <span class="o">&lt;&lt;</span> <span class="n">size</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; dla typu &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">type_name</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;: &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">duration</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; milisekund&#34;</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Przetestuj mnożenie macierzy dla różnych rozmiarów i typów danych
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">test_matrix_multiplication</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="s">&#34;int&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_matrix_multiplication</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="s">&#34;float&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_matrix_multiplication</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">100</span><span class="p">,</span> <span class="s">&#34;double&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">test_matrix_multiplication</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">500</span><span class="p">,</span> <span class="s">&#34;int&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_matrix_multiplication</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">500</span><span class="p">,</span> <span class="s">&#34;float&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_matrix_multiplication</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">500</span><span class="p">,</span> <span class="s">&#34;double&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">test_matrix_multiplication</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">1000</span><span class="p">,</span> <span class="s">&#34;int&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_matrix_multiplication</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">1000</span><span class="p">,</span> <span class="s">&#34;float&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_matrix_multiplication</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">1000</span><span class="p">,</span> <span class="s">&#34;double&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Porównaj wyniki i omów znaczenie różnic w czasie wykonania dla różnych typów danych.&#34;</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Program mnoży dwie macierze o ustalonych rozmiarach, używając typów stałoprzecinkowych (<code>int</code>) oraz zmiennoprzecinkowych (<code>float</code>, <code>double</code>). Następnie, mierzy czas wykonania mnożenia macierzy dla różnych rozmiarów macierzy (100x100, 500x500, 1000x1000) i porównuje wyniki dla różnych typów danych.</p>
<p>Po skompilowaniu i uruchomieniu programu, na konsoli zostaną wyświetlone wyniki czasu wykonania mnożenia macierzy dla różnych rozmiarów macierzy i typów danych. Porównaj wyniki i omów znaczenie różnic w czasie wykonania dla różnych typów danych.</p>
<p>Wyniki mogą się różnić w zależności od sprzętu i kompilatora. Analizuj różnice między typami danych (stałoprzecinkowe i zmiennoprzecinkowe) oraz rozmiarami macierzy. Zwróć uwagę na to, jak zmienia się czas wykonania w zależności od typu danych i rozmiaru macierzy. Zastanów się, jak te różnice wpływają na wydajność w praktycznych zastosowaniach, takich jak obliczenia naukowe, analiza danych czy grafika komputerowa.</p>
<p>W praktyce, wybór między typami danych zależy od wymagań dotyczących precyzji, wydajności i dostępnych zasobów. W przypadku obliczeń naukowych i analizy danych, precyzja może być kluczowa, ale jednocześnie może wpłynąć na czas wykonania. W grafice komputerowej, mniejsza precyzja może być akceptowalna, ale szybsze obliczenia mogą być kluczowe dla płynności działania aplikacji.</p>
<h2 id="eksperyment-z-optymalizacją-kodu">Eksperyment z optymalizacją kodu.</h2>
<ol>
<li>Napisz prosty program, który wykonuje operacje matematyczne na liczbach stało- i zmiennoprzecinkowych.</li>
<li>Skompiluj i uruchom program z różnymi poziomami optymalizacji (np. -O0, -O1, -O2, -O3).</li>
<li>Porównaj czas wykonania programu dla różnych poziomów optymalizacji i zastanów się, jak optymalizacja wpływa na wydajność operacji stało- i zmiennoprzecinkowych.</li>
</ol>
<h2 id="wprowadzenie-do-instrukcji-simd">Wprowadzenie do instrukcji SIMD.</h2>
<ol>
<li>Zapoznaj się z instrukcjami SIMD (Single Instruction, Multiple Data) dostępnymi dla Twojego procesora (np. SSE, AVX).</li>
<li>Napisz program, który wykonuje operacje matematyczne na wektorach liczb stało- i zmiennoprzecinkowych, wykorzystując instrukcje SIMD.</li>
<li>Porównaj czas wykonania operacji wektorowych z użyciem SIMD do czasu wykonania operacji</li>
</ol>
<p>Aby użyć instrukcji SIMD w C++, możemy wykorzystać bibliotekę <code>immintrin.h</code>, która obsługuje instrukcje SSE, SSE2, SSE3, SSSE3, SSE4.1, SSE4.2, AVX, AVX2 i AVX-512.</p>
<p>Poniżej znajduje się przykład programu w C++, który wykonuje operacje dodawania na wektorach liczb stało- i zmiennoprzecinkowych, wykorzystując instrukcje SIMD. Porównuje czas wykonania operacji wektorowych z użyciem SIMD do czasu wykonania operacji bez SIMD.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span><span class="lnt">54
</span><span class="lnt">55
</span><span class="lnt">56
</span><span class="lnt">57
</span><span class="lnt">58
</span><span class="lnt">59
</span><span class="lnt">60
</span><span class="lnt">61
</span><span class="lnt">62
</span><span class="lnt">63
</span><span class="lnt">64
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;chrono&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;immintrin.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="k">using</span> <span class="k">namespace</span> <span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">const</span> <span class="kt">int</span> <span class="n">vector_size</span> <span class="o">=</span> <span class="mi">1000000</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">add_vectors</span><span class="p">(</span><span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">b</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">result</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="n">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">a</span><span class="p">.</span><span class="n">size</span><span class="p">();</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">result</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">+</span> <span class="n">b</span><span class="p">[</span><span class="n">i</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">add_vectors_simd</span><span class="p">(</span><span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">a</span><span class="p">,</span> <span class="k">const</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">b</span><span class="p">,</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span> <span class="o">&amp;</span><span class="n">result</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">size_t</span> <span class="n">simd_length</span> <span class="o">=</span> <span class="n">a</span><span class="p">.</span><span class="n">size</span><span class="p">()</span> <span class="o">/</span> <span class="mi">8</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="n">size_t</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">simd_length</span><span class="p">;</span> <span class="o">++</span><span class="n">i</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">__m256</span> <span class="n">vec_a</span> <span class="o">=</span> <span class="n">_mm256_loadu_ps</span><span class="p">(</span><span class="o">&amp;</span><span class="n">a</span><span class="p">[</span><span class="n">i</span> <span class="o">*</span> <span class="mi">8</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">        <span class="n">__m256</span> <span class="n">vec_b</span> <span class="o">=</span> <span class="n">_mm256_loadu_ps</span><span class="p">(</span><span class="o">&amp;</span><span class="n">b</span><span class="p">[</span><span class="n">i</span> <span class="o">*</span> <span class="mi">8</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">        <span class="n">__m256</span> <span class="n">vec_result</span> <span class="o">=</span> <span class="n">_mm256_add_ps</span><span class="p">(</span><span class="n">vec_a</span><span class="p">,</span> <span class="n">vec_b</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">_mm256_storeu_ps</span><span class="p">(</span><span class="o">&amp;</span><span class="n">result</span><span class="p">[</span><span class="n">i</span> <span class="o">*</span> <span class="mi">8</span><span class="p">],</span> <span class="n">vec_result</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">template</span> <span class="o">&lt;</span><span class="k">typename</span> <span class="n">T</span><span class="o">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="n">test_add_vectors</span><span class="p">(</span><span class="k">const</span> <span class="n">string</span> <span class="o">&amp;</span><span class="n">type_name</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">a</span><span class="p">(</span><span class="n">vector_size</span><span class="p">,</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">1</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">b</span><span class="p">(</span><span class="n">vector_size</span><span class="p">,</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">2</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span> <span class="n">result</span><span class="p">(</span><span class="n">vector_size</span><span class="p">,</span> <span class="k">static_cast</span><span class="o">&lt;</span><span class="n">T</span><span class="o">&gt;</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">auto</span> <span class="n">start_time</span> <span class="o">=</span> <span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">now</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="n">add_vectors</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">result</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">auto</span> <span class="n">end_time</span> <span class="o">=</span> <span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">now</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">auto</span> <span class="n">duration</span> <span class="o">=</span> <span class="n">duration_cast</span><span class="o">&lt;</span><span class="n">milliseconds</span><span class="o">&gt;</span><span class="p">(</span><span class="n">end_time</span> <span class="o">-</span> <span class="n">start_time</span><span class="p">).</span><span class="n">count</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Czas wykonania dodawania wektorów bez SIMD dla &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">type_name</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;: &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">duration</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; ms&#34;</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">test_add_vectors_simd_float</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span> <span class="n">a</span><span class="p">(</span><span class="n">vector_size</span><span class="p">,</span> <span class="mf">1.0f</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span> <span class="n">b</span><span class="p">(</span><span class="n">vector_size</span><span class="p">,</span> <span class="mf">2.0f</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">vector</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span> <span class="n">result</span><span class="p">(</span><span class="n">vector_size</span><span class="p">,</span> <span class="mf">0.0f</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">auto</span> <span class="n">start_time</span> <span class="o">=</span> <span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">now</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="n">add_vectors_simd</span><span class="p">(</span><span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">,</span> <span class="n">result</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">auto</span> <span class="n">end_time</span> <span class="o">=</span> <span class="n">high_resolution_clock</span><span class="o">::</span><span class="n">now</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">auto</span> <span class="n">duration</span> <span class="o">=</span> <span class="n">duration_cast</span><span class="o">&lt;</span><span class="n">milliseconds</span><span class="o">&gt;</span><span class="p">(</span><span class="n">end_time</span> <span class="o">-</span> <span class="n">start_time</span><span class="p">).</span><span class="n">count</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Czas wykonania dodawania wektorów z użyciem SIMD dla float: &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">duration</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; ms&#34;</span> <span class="o">&lt;&lt;</span> <span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_add_vectors</span><span class="o">&lt;</span><span class="kt">int</span><span class="o">&gt;</span><span class="p">(</span><span class="s">&#34;int&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_add_vectors</span><span class="o">&lt;</span><span class="kt">float</span><span class="o">&gt;</span><span class="p">(</span><span class="s">&#34;float&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">test_add_vectors</span><span class="o">&lt;</span><span class="kt">double</span><span class="o">&gt;</span><span class="p">(</span><span class="s">&#34;double&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">test_add_vectors_simd_float</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>W tym przypadku, używamy instrukcji SIMD dla operacji dodawania wektorów zmiennoprzecinkowych (<code>float</code>). Program porównuje czas wykonania operacji wektorowych z użyciem SIMD do czasu wykonania operacji bez SIMD dla typów <code>int</code>, <code>float</code> i <code>double</code>. Po skompilowaniu i uruchomieniu programu, na konsoli zostaną wyświetlone wyniki czasu wykonania dodawania wektorów dla różnych typów danych, zarówno z użyciem SIMD, jak i bez.</p>
<p>Wyniki mogą się różnić w zależności od sprzętu i kompilatora, ale zazwyczaj SIMD przyspiesza obliczenia wektorowe, gdyż pozwala na wykonywanie operacji na wielu elementach danych jednocześnie.</p>
<p>W praktyce, wykorzystanie SIMD może prowadzić do znacznego przyspieszenia obliczeń wektorowych, szczególnie w zastosowaniach, takich jak grafika komputerowa, analiza danych czy przetwarzanie sygnałów. Jednak warto pamiętać, że nie wszystkie operacje mogą być przyspieszone przy użyciu SIMD, a także, że optymalizacja przy użyciu SIMD może zwiększyć złożoność kodu i utrudnić jego utrzymanie.</p>
<blockquote>
<p>Ref:</p>
<ul>
<li><a href="https://www.cppstories.com/2014/04/presentation-native-code-performance-on-modern-cpus/">Native code performance on modern CPUs</a></li>
</ul>
</blockquote>
<h1 id="porównawczy-kod-w-asemblerze">Porównawczy kod w asemblerze</h1>
<p>Poniżej znajduje się przykład programu napisanego w asemblerze x86, który porównuje czas wykonania operacji dodawania, odejmowania, mnożenia i dzielenia dla liczby stałoprzecinkowej (int) i zmiennoprzecinkowej (float, double). Program korzysta z polecenia RDTSC do mierzenia czasu wykonania operacji.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-nasm" data-lang="nasm"><span class="line"><span class="cl"><span class="nf">format</span> <span class="nv">PE</span> <span class="nv">GUI</span> <span class="mf">4.0</span>
</span></span><span class="line"><span class="cl"><span class="nf">entry</span> <span class="nv">start</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nf">include</span> <span class="s">&#39;win32w.inc&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">section</span> <span class="s">&#39;.text&#39;</span> <span class="nv">code</span> <span class="nv">readable</span> <span class="nv">executable</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nl">start:</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Licznik petli dla liczby staloprzecinkowej (int)</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mov</span> <span class="nb">ecx</span><span class="p">,</span> <span class="p">[</span><span class="nv">iterations</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Pobranie czasu startowego</span>
</span></span><span class="line"><span class="cl">    <span class="nf">rdtsc</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mov</span> <span class="nb">edi</span><span class="p">,</span> <span class="nb">eax</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nl">int_loop:</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nf">mov</span> <span class="nb">eax</span><span class="p">,</span> <span class="p">[</span><span class="nv">int_a</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mov</span> <span class="nb">ebx</span><span class="p">,</span> <span class="p">[</span><span class="nv">int_b</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Dodawanie</span>
</span></span><span class="line"><span class="cl">    <span class="nf">add</span> <span class="nb">eax</span><span class="p">,</span> <span class="nb">ebx</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Odejmowanie</span>
</span></span><span class="line"><span class="cl">    <span class="nf">sub</span> <span class="nb">eax</span><span class="p">,</span> <span class="nb">ebx</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Mnozenie</span>
</span></span><span class="line"><span class="cl">    <span class="nf">imul</span> <span class="nb">eax</span><span class="p">,</span> <span class="nb">ebx</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Dzielenie</span>
</span></span><span class="line"><span class="cl">    <span class="nf">xor</span> <span class="nb">edx</span><span class="p">,</span> <span class="nb">edx</span>
</span></span><span class="line"><span class="cl">    <span class="nf">idiv</span> <span class="nb">ebx</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Nastepna iteracja</span>
</span></span><span class="line"><span class="cl">    <span class="nf">loop</span> <span class="nv">int_loop</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Pobranie czasu koncowego</span>
</span></span><span class="line"><span class="cl">    <span class="nf">rdtsc</span>
</span></span><span class="line"><span class="cl">    <span class="nf">sub</span> <span class="nb">eax</span><span class="p">,</span> <span class="nb">edi</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mov</span> <span class="p">[</span><span class="nv">int_duration</span><span class="p">],</span> <span class="nb">eax</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Licznik petli dla liczby zmiennoprzecinkowej (float)</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mov</span> <span class="nb">ecx</span><span class="p">,</span> <span class="p">[</span><span class="nv">iterations</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Pobranie czasu startowego</span>
</span></span><span class="line"><span class="cl">    <span class="nf">rdtsc</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mov</span> <span class="nb">edi</span><span class="p">,</span> <span class="nb">eax</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nl">float_loop:</span>
</span></span><span class="line"><span class="cl">    <span class="c1">; Wczytanie liczb zmiennoprzecinkowych do rejestrów</span>
</span></span><span class="line"><span class="cl">    <span class="nf">fld</span> <span class="p">[</span><span class="nv">float_a</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="nf">fld</span> <span class="p">[</span><span class="nv">float_b</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Dodawanie</span>
</span></span><span class="line"><span class="cl">    <span class="nf">faddp</span> <span class="nb">st1</span><span class="p">,</span> <span class="nb">st0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Odejmowanie</span>
</span></span><span class="line"><span class="cl">    <span class="nf">fsubp</span> <span class="nb">st1</span><span class="p">,</span> <span class="nb">st0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Mnozenie</span>
</span></span><span class="line"><span class="cl">    <span class="nf">fmulp</span> <span class="nb">st1</span><span class="p">,</span> <span class="nb">st0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Dzielenie</span>
</span></span><span class="line"><span class="cl">    <span class="nf">fdivp</span> <span class="nb">st1</span><span class="p">,</span> <span class="nb">st0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Nastepna iteracja</span>
</span></span><span class="line"><span class="cl">    <span class="nf">loop</span> <span class="nv">float_loop</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Pobranie czasu koncowego</span>
</span></span><span class="line"><span class="cl">    <span class="nf">rdtsc</span>
</span></span><span class="line"><span class="cl">    <span class="nf">sub</span> <span class="nb">eax</span><span class="p">,</span> <span class="nb">edi</span>
</span></span><span class="line"><span class="cl">    <span class="nf">mov</span> <span class="p">[</span><span class="nv">float_duration</span><span class="p">],</span> <span class="nb">eax</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">; Zakonczenie programu</span>
</span></span><span class="line"><span class="cl">    <span class="nf">invoke</span> <span class="nv">ExitProcess</span><span class="p">,</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">section</span> <span class="s">&#39;.data&#39;</span> <span class="nv">data</span> <span class="nv">readable</span> <span class="nv">writeable</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nf">iterations</span> <span class="nv">dd</span> <span class="mi">1000000</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">; Stale dla liczb staloprzecinkowych</span>
</span></span><span class="line"><span class="cl">  <span class="nf">int_a</span> <span class="nv">dd</span> <span class="mi">123</span>
</span></span><span class="line"><span class="cl">  <span class="nf">int_b</span> <span class="nv">dd</span> <span class="mi">456</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">; Stale dla liczb zmiennoprzecinkowych</span>
</span></span><span class="line"><span class="cl">  <span class="nf">float_a</span> <span class="nv">dd</span> <span class="mf">123.456</span><span class="nv">f</span>
</span></span><span class="line"><span class="cl">  <span class="nf">float_b</span> <span class="nv">dd</span> <span class="mf">456.789</span><span class="nv">f</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="c1">; Rezerwacja miejsca na zmienne</span>
</span></span><span class="line"><span class="cl">  <span class="nf">int_duration</span> <span class="nv">dd</span> <span class="nv">?</span>
</span></span><span class="line"><span class="cl">  <span class="nf">float_duration</span> <span class="nv">dd</span> <span class="nv">?</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">section</span> <span class="s">&#39;.idata&#39;</span> <span class="nv">import</span> <span class="nv">data</span> <span class="nv">readable</span> <span class="nv">writeable</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="k">library</span> <span class="nv">kernel32</span><span class="p">,</span><span class="s">&#39;KERNEL32.DLL&#39;</span><span class="p">,</span><span class="err">\</span>
</span></span><span class="line"><span class="cl">  <span class="nf">user32</span><span class="p">,</span><span class="s">&#39;USER32.DLL&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nf">include</span> <span class="s">&#39;api\kernel32.inc&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="nf">include</span> <span class="s">&#39;api\user32.inc&#39;</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Aby skompilować i uruchomić program, można użyć narzędzi NASM i LD lub fasm</p>
<p>Należy pamiętać, że ten program nie wypisuje wyników na ekran, ale przechowuje je w zarezerwowanych zmiennych <code>int_duration</code> i <code>float_duration</code>. Aby wyświetlić wyniki, można dodać kod odpowiedzialny za wypisanie wartości na ekran, korzystając z systemu wywołań (syscalls) lub użyć debuggera, aby przejrzeć wartości tych zmiennych</p>
<blockquote>
<p>Ref:</p>
<ul>
<li><a href="https://x64dbg.com/">x64dbg</a></li>
</ul>
</blockquote>
<h1 id="architektura-von-neumana">Architektura von Neumana</h1>
<p>Architektura komputerów Von-Neumanna, zaproponowana przez Johna von Neumanna, opiera się na koncepcji przechowywania programów w pamięci komputera. Wcześniej, maszyny liczące były projektowane tak, aby wykonywać jedno konkretne zadanie i nie można było ich przeprogramować. Architektura von Neumanna wprowadziła założenie, że programy i dane mogą być przechowywane w tej samej pamięci, co umożliwiło rozwój maszyn uniwersalnych, które mogą wykonywać różne zadania.</p>
<p><img loading="lazy" src="/images/basic_structure.png" type="" alt="Architektura von Neumana"  /></p>
<p>Podstawowe elementy architektury von Neumanna obejmują:</p>
<ol>
<li>
<p>Pamięć: Służy do przechowywania danych i programów. Pamięć może być podzielona na dwie części: pamięć operacyjną (RAM) i pamięć trwałą (np. dysk twardy).</p>
</li>
<li>
<p>Procesor: Składa się z jednostki arytmetyczno-logicznej (ALU) oraz jednostki sterującej. ALU wykonuje operacje arytmetyczne i logiczne na danych, podczas gdy jednostka sterująca zarządza sekwencją operacji, odczytuje instrukcje z pamięci i decyduje, jakie operacje mają zostać wykonane.</p>
</li>
<li>
<p>Wejście/wyjście (I/O): Odpowiada za komunikację z urządzeniami zewnętrznymi, takimi jak klawiatura, mysz, monitor, drukarka itp.</p>
</li>
<li>
<p>System komunikacji: Składa się z szyny danych, szyny adresowej i szyny kontrolnej, które łączą poszczególne elementy komputera i umożliwiają wymianę informacji między nimi.</p>
</li>
</ol>
<p>Architektura komputerów Von-Neumanna jest podstawą dla większości współczesnych komputerów i urządzeń, takich jak komputery osobiste, laptopy, serwery czy smartfony. Wraz z postępem technologicznym i rozwojem układów scalonych oraz mikroprocesorów, architektura von Neumanna została udoskonalona i przekształcona, ale jej podstawowe zasady wciąż pozostają aktualne.</p>
<p>ISA (Instruction set architecture) i posiada trzy podstawowe jednostki:</p>
<ol>
<li>Centralna Jednostka Przetwarzająca (CPU)
<ol>
<li>Control Unit(CU)</li>
<li>Jednostka arytmetyczna i logiczna (ALU)</li>
<li>Rejestry</li>
</ol>
</li>
<li>Jednostka pamięci głównej</li>
<li>Urządzenie wejścia/wyjścia</li>
</ol>
<h2 id="przykładowa-symulacja-architektury">Przykładowa symulacja architektury</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c#" data-lang="c#"><span class="line"><span class="cl"><span class="k">using</span> <span class="nn">System</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ControlUnit</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">ProgramCounter</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">MemoryAddressRegister</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">MemoryDataRegister</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">CurrentInstructionRegister</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">InstructionBufferRegister</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">ControlUnit</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ProgramCounter</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">MemoryAddressRegister</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">MemoryDataRegister</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">CurrentInstructionRegister</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">InstructionBufferRegister</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">FetchInstruction</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">ExecuteInstruction</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ALU</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">Accumulator</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">ALU</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Accumulator</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Add</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Subtract</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Compare</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">PerformLogicOperation</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">,</span> <span class="kt">string</span> <span class="n">operation</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">ShiftBits</span><span class="p">(</span><span class="kt">int</span> <span class="k">value</span><span class="p">,</span> <span class="kt">string</span> <span class="n">direction</span><span class="p">,</span> <span class="kt">int</span> <span class="n">amount</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CPU</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">ControlUnit</span> <span class="n">ControlUnit</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">ALU</span> <span class="n">Alu</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">CPU</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ControlUnit</span> <span class="p">=</span> <span class="k">new</span> <span class="n">ControlUnit</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="n">Alu</span> <span class="p">=</span> <span class="k">new</span> <span class="n">ALU</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Run</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">MainMemory</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span><span class="p">[]</span> <span class="n">Memory</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">MainMemory</span><span class="p">(</span><span class="kt">int</span> <span class="n">size</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Memory</span> <span class="p">=</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[</span><span class="n">size</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Read</span><span class="p">(</span><span class="kt">int</span> <span class="n">address</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Write</span><span class="p">(</span><span class="kt">int</span> <span class="n">address</span><span class="p">,</span> <span class="kt">int</span> <span class="k">value</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">IODevice</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">InputData</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">OutputData</span><span class="p">(</span><span class="kt">int</span> <span class="n">data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Computer</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">CPU</span> <span class="n">Cpu</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">MainMemory</span> <span class="n">Memory</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">IODevice</span> <span class="n">IoDevice</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">Computer</span><span class="p">(</span><span class="kt">int</span> <span class="n">memorySize</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Cpu</span> <span class="p">=</span> <span class="k">new</span> <span class="n">CPU</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="n">Memory</span> <span class="p">=</span> <span class="k">new</span> <span class="n">MainMemory</span><span class="p">(</span><span class="n">memorySize</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">IoDevice</span> <span class="p">=</span> <span class="k">new</span> <span class="n">IODevice</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">LoadProgram</span><span class="p">(</span><span class="kt">int</span><span class="p">[]</span> <span class="n">program</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Run</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Program</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">static</span> <span class="k">void</span> <span class="n">Main</span><span class="p">(</span><span class="kt">string</span><span class="p">[]</span> <span class="n">args</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Computer</span> <span class="n">computer</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Computer</span><span class="p">(</span><span class="n">memorySize</span><span class="p">:</span> <span class="m">1024</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// Load a program into the computer</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// computer.LoadProgram(program);</span>
</span></span><span class="line"><span class="cl">        <span class="n">computer</span><span class="p">.</span><span class="n">Run</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>Przykład Lab_31.py</strong></p>
<h2 id="instrukcje-symulatora">Instrukcje symulatora</h2>
<p>Procesor posiada tylko jeden rejestr, akumulator A. Możliwe jest adresowanie bezpośrednie i pośrednie. Załóżmy, że akumulator jest 32bitowy.</p>
<ul>
<li>HLT  - Zatrzymanie pracy</li>
<li>LDA &lt;&gt; - Załadowanie do <strong>A</strong> danych z adresu</li>
<li>STA  - Wpisanie pod zadany adres w argumencie, wartości z rejestru A</li>
<li>LDI  - Załadowanie do <strong>A</strong> danych z adresu wskzanego pod podanym adresem</li>
<li>INP  - Załadowanie danych do A z urządzenia we/wy</li>
<li>OUT  - Wysłanie wartości A na wyjście</li>
<li>ADD  - Dodanie wartości z pamięci wskazanej przez argument do <strong>A</strong></li>
<li>SUB  - Odjęcie od <strong>A</strong> wartości z pamięci wskazanej przez argument</li>
<li>CMP  - Porównanie <strong>A</strong> z wartoścą pamięci wskazanej przez argument, wynik w <strong>A</strong> 0 jesli równe, 1 jeśli różne</li>
<li>MOV  - Wpisanie do <strong>A</strong> bezpośredniej wartości</li>
<li>INC  - Zwiększenie <strong>A</strong> o jeden</li>
<li>DEC  - Zmniejszenie <strong>A</strong> o jeden</li>
<li>JMP  - Skok bezwarunkowy</li>
<li>JZ   - Skok jeśli <strong>A</strong> jest równe zero</li>
</ul>
<p>Składnia assemblera:</p>
<p>:etykieta - etykieta, wskazująca na miejsce w pamięci</p>
<p>@etykieta - poinformowanie kompilator, aby zamienił wskazanie na adres etykiety w pamięci</p>
<p>Przykłady:</p>
<p>Wypisanie liczby 10 na wyjście</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">    MOV 10
</span></span><span class="line"><span class="cl">    OUT
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    HLT
</span></span></code></pre></td></tr></table>
</div>
</div><p>Dodawanie</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">    MOV 10
</span></span><span class="line"><span class="cl">    STA @value 
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    MOV 15
</span></span><span class="line"><span class="cl">    ADD @value
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    OUT
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    HLT
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:value
</span></span><span class="line"><span class="cl">    0
</span></span></code></pre></td></tr></table>
</div>
</div><p>Adresowanie bezpośrednie</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">    LDA @location
</span></span><span class="line"><span class="cl">    OUT
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    HLT
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:value
</span></span><span class="line"><span class="cl">    42
</span></span></code></pre></td></tr></table>
</div>
</div><p>Adresowanie pośrednie</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">    LDI @location
</span></span><span class="line"><span class="cl">    OUT
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    MOV 42
</span></span><span class="line"><span class="cl">    STA @value
</span></span><span class="line"><span class="cl">    LDI @location
</span></span><span class="line"><span class="cl">    OUT
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    HLT
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:location
</span></span><span class="line"><span class="cl">    @value
</span></span><span class="line"><span class="cl">:value
</span></span><span class="line"><span class="cl">    37
</span></span></code></pre></td></tr></table>
</div>
</div><p>Pętla</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">    MOV 10
</span></span><span class="line"><span class="cl">:loop
</span></span><span class="line"><span class="cl">    OUT
</span></span><span class="line"><span class="cl">    DEC
</span></span><span class="line"><span class="cl">    JZ @exit
</span></span><span class="line"><span class="cl">    JMP @loop
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">:exit
</span></span><span class="line"><span class="cl">    OUT
</span></span><span class="line"><span class="cl">    HLT
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>Ćwiczenia</strong></p>
<p>dodac dwie liczby znajdujące się w pamięci</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">:value
</span></span><span class="line"><span class="cl">    3
</span></span><span class="line"><span class="cl">    141
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>wypisac liczby znajdujące się w pamięci az napotkamy 0:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">:value
</span></span><span class="line"><span class="cl">    3
</span></span><span class="line"><span class="cl">    141
</span></span><span class="line"><span class="cl">    5
</span></span><span class="line"><span class="cl">    92
</span></span><span class="line"><span class="cl">    65
</span></span><span class="line"><span class="cl">    35
</span></span><span class="line"><span class="cl">    89
</span></span><span class="line"><span class="cl">    79
</span></span><span class="line"><span class="cl">    0
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>zsumować liczby znajdujące się w pamięci, zakończyć jak napotkamy 0:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">:value
</span></span><span class="line"><span class="cl">    1
</span></span><span class="line"><span class="cl">    2
</span></span><span class="line"><span class="cl">    3
</span></span><span class="line"><span class="cl">    4
</span></span><span class="line"><span class="cl">    5
</span></span><span class="line"><span class="cl">    6
</span></span><span class="line"><span class="cl">    7
</span></span><span class="line"><span class="cl">    8
</span></span><span class="line"><span class="cl">    0
</span></span></code></pre></td></tr></table>
</div>
</div><ul>
<li>wypisac na wyjście kolejne wartości ciągu fibonacciego, kilka pierwszych. Dla uproszczenia można dwie początkowe zapisać od razu w kodzie, np.:</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">    :fib1
</span></span><span class="line"><span class="cl">    0
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    :fib2
</span></span><span class="line"><span class="cl">    1
</span></span></code></pre></td></tr></table>
</div>
</div><h2 id="symulator">Symulator</h2>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span><span class="lnt">164
</span><span class="lnt">165
</span><span class="lnt">166
</span><span class="lnt">167
</span><span class="lnt">168
</span><span class="lnt">169
</span><span class="lnt">170
</span><span class="lnt">171
</span><span class="lnt">172
</span><span class="lnt">173
</span><span class="lnt">174
</span><span class="lnt">175
</span><span class="lnt">176
</span><span class="lnt">177
</span><span class="lnt">178
</span><span class="lnt">179
</span><span class="lnt">180
</span><span class="lnt">181
</span><span class="lnt">182
</span><span class="lnt">183
</span><span class="lnt">184
</span><span class="lnt">185
</span><span class="lnt">186
</span><span class="lnt">187
</span><span class="lnt">188
</span><span class="lnt">189
</span><span class="lnt">190
</span><span class="lnt">191
</span><span class="lnt">192
</span><span class="lnt">193
</span><span class="lnt">194
</span><span class="lnt">195
</span><span class="lnt">196
</span><span class="lnt">197
</span><span class="lnt">198
</span><span class="lnt">199
</span><span class="lnt">200
</span><span class="lnt">201
</span><span class="lnt">202
</span><span class="lnt">203
</span><span class="lnt">204
</span><span class="lnt">205
</span><span class="lnt">206
</span><span class="lnt">207
</span><span class="lnt">208
</span><span class="lnt">209
</span><span class="lnt">210
</span><span class="lnt">211
</span><span class="lnt">212
</span><span class="lnt">213
</span><span class="lnt">214
</span><span class="lnt">215
</span><span class="lnt">216
</span><span class="lnt">217
</span><span class="lnt">218
</span><span class="lnt">219
</span><span class="lnt">220
</span><span class="lnt">221
</span><span class="lnt">222
</span><span class="lnt">223
</span><span class="lnt">224
</span><span class="lnt">225
</span><span class="lnt">226
</span><span class="lnt">227
</span><span class="lnt">228
</span><span class="lnt">229
</span><span class="lnt">230
</span><span class="lnt">231
</span><span class="lnt">232
</span><span class="lnt">233
</span><span class="lnt">234
</span><span class="lnt">235
</span><span class="lnt">236
</span><span class="lnt">237
</span><span class="lnt">238
</span><span class="lnt">239
</span><span class="lnt">240
</span><span class="lnt">241
</span><span class="lnt">242
</span><span class="lnt">243
</span><span class="lnt">244
</span><span class="lnt">245
</span><span class="lnt">246
</span><span class="lnt">247
</span><span class="lnt">248
</span><span class="lnt">249
</span><span class="lnt">250
</span><span class="lnt">251
</span><span class="lnt">252
</span><span class="lnt">253
</span><span class="lnt">254
</span><span class="lnt">255
</span><span class="lnt">256
</span><span class="lnt">257
</span><span class="lnt">258
</span><span class="lnt">259
</span><span class="lnt">260
</span><span class="lnt">261
</span><span class="lnt">262
</span><span class="lnt">263
</span><span class="lnt">264
</span><span class="lnt">265
</span><span class="lnt">266
</span><span class="lnt">267
</span><span class="lnt">268
</span><span class="lnt">269
</span><span class="lnt">270
</span><span class="lnt">271
</span><span class="lnt">272
</span><span class="lnt">273
</span><span class="lnt">274
</span><span class="lnt">275
</span><span class="lnt">276
</span><span class="lnt">277
</span><span class="lnt">278
</span><span class="lnt">279
</span><span class="lnt">280
</span><span class="lnt">281
</span><span class="lnt">282
</span><span class="lnt">283
</span><span class="lnt">284
</span><span class="lnt">285
</span><span class="lnt">286
</span><span class="lnt">287
</span><span class="lnt">288
</span><span class="lnt">289
</span><span class="lnt">290
</span><span class="lnt">291
</span><span class="lnt">292
</span><span class="lnt">293
</span><span class="lnt">294
</span><span class="lnt">295
</span><span class="lnt">296
</span><span class="lnt">297
</span><span class="lnt">298
</span><span class="lnt">299
</span><span class="lnt">300
</span><span class="lnt">301
</span><span class="lnt">302
</span><span class="lnt">303
</span><span class="lnt">304
</span><span class="lnt">305
</span><span class="lnt">306
</span><span class="lnt">307
</span><span class="lnt">308
</span><span class="lnt">309
</span><span class="lnt">310
</span><span class="lnt">311
</span><span class="lnt">312
</span><span class="lnt">313
</span><span class="lnt">314
</span><span class="lnt">315
</span><span class="lnt">316
</span><span class="lnt">317
</span><span class="lnt">318
</span><span class="lnt">319
</span><span class="lnt">320
</span><span class="lnt">321
</span><span class="lnt">322
</span><span class="lnt">323
</span><span class="lnt">324
</span><span class="lnt">325
</span><span class="lnt">326
</span><span class="lnt">327
</span><span class="lnt">328
</span><span class="lnt">329
</span><span class="lnt">330
</span><span class="lnt">331
</span><span class="lnt">332
</span><span class="lnt">333
</span><span class="lnt">334
</span><span class="lnt">335
</span><span class="lnt">336
</span><span class="lnt">337
</span><span class="lnt">338
</span><span class="lnt">339
</span><span class="lnt">340
</span><span class="lnt">341
</span><span class="lnt">342
</span><span class="lnt">343
</span><span class="lnt">344
</span><span class="lnt">345
</span><span class="lnt">346
</span><span class="lnt">347
</span><span class="lnt">348
</span><span class="lnt">349
</span><span class="lnt">350
</span><span class="lnt">351
</span><span class="lnt">352
</span><span class="lnt">353
</span><span class="lnt">354
</span><span class="lnt">355
</span><span class="lnt">356
</span><span class="lnt">357
</span><span class="lnt">358
</span><span class="lnt">359
</span><span class="lnt">360
</span><span class="lnt">361
</span><span class="lnt">362
</span><span class="lnt">363
</span><span class="lnt">364
</span><span class="lnt">365
</span><span class="lnt">366
</span><span class="lnt">367
</span><span class="lnt">368
</span><span class="lnt">369
</span><span class="lnt">370
</span><span class="lnt">371
</span><span class="lnt">372
</span><span class="lnt">373
</span><span class="lnt">374
</span><span class="lnt">375
</span><span class="lnt">376
</span><span class="lnt">377
</span><span class="lnt">378
</span><span class="lnt">379
</span><span class="lnt">380
</span><span class="lnt">381
</span><span class="lnt">382
</span><span class="lnt">383
</span><span class="lnt">384
</span><span class="lnt">385
</span><span class="lnt">386
</span><span class="lnt">387
</span><span class="lnt">388
</span><span class="lnt">389
</span><span class="lnt">390
</span><span class="lnt">391
</span><span class="lnt">392
</span><span class="lnt">393
</span><span class="lnt">394
</span><span class="lnt">395
</span><span class="lnt">396
</span><span class="lnt">397
</span><span class="lnt">398
</span><span class="lnt">399
</span><span class="lnt">400
</span><span class="lnt">401
</span><span class="lnt">402
</span><span class="lnt">403
</span><span class="lnt">404
</span><span class="lnt">405
</span><span class="lnt">406
</span><span class="lnt">407
</span><span class="lnt">408
</span><span class="lnt">409
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-c#" data-lang="c#"><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">ioDevice</span> <span class="p">=</span> <span class="k">new</span> <span class="n">IODevice</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">computer</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Computer</span><span class="p">(</span><span class="m">256</span><span class="p">,</span> <span class="n">ioDevice</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">compiler</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Compiler</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="kt">var</span> <span class="n">compiledProgram</span> <span class="p">=</span> <span class="n">compiler</span><span class="p">.</span><span class="n">Compile</span><span class="p">(</span><span class="n">sourceCode_dump</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">computer</span><span class="p">.</span><span class="n">LoadProgram</span><span class="p">(</span><span class="n">compiledProgram</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="n">computer</span><span class="p">.</span><span class="n">Run</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">enum</span> <span class="n">OpCode</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">HLT</span> <span class="p">=</span> <span class="m">0x00</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">LDA</span> <span class="p">=</span> <span class="m">0x01</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">STA</span> <span class="p">=</span> <span class="m">0x02</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">LDI</span> <span class="p">=</span> <span class="m">0x03</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">INP</span> <span class="p">=</span> <span class="m">0x04</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">OUT</span> <span class="p">=</span> <span class="m">0x05</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">ADD</span> <span class="p">=</span> <span class="m">0x06</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">SUB</span> <span class="p">=</span> <span class="m">0x07</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">CMP</span> <span class="p">=</span> <span class="m">0x08</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">MOV</span> <span class="p">=</span> <span class="m">0x09</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">INC</span> <span class="p">=</span> <span class="m">0x0a</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">DEC</span> <span class="p">=</span> <span class="m">0x0b</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">JMP</span> <span class="p">=</span> <span class="m">0x0c</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">JZ</span>  <span class="p">=</span> <span class="m">0x0d</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="n">MEM</span> <span class="p">=</span> <span class="m">0x0e</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">DB</span>  <span class="p">=</span> <span class="m">0x0</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ControlUnit</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kt">bool</span> <span class="n">_debug</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kt">int</span> <span class="n">ProgramCounter</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kt">int</span> <span class="n">MemoryAddressRegister</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kt">int</span> <span class="n">MemoryDataRegister</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kt">int</span> <span class="n">CurrentInstructionRegister</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">ControlUnit</span><span class="p">(</span><span class="kt">bool</span> <span class="n">debug</span> <span class="p">=</span> <span class="kc">false</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">_debug</span> <span class="p">=</span> <span class="n">debug</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">ProgramCounter</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">MemoryAddressRegister</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">MemoryDataRegister</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">CurrentInstructionRegister</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">FetchInstruction</span><span class="p">(</span><span class="n">MainMemory</span> <span class="n">memory</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">MemoryAddressRegister</span> <span class="p">=</span> <span class="n">ProgramCounter</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">MemoryDataRegister</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">MemoryAddressRegister</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">CurrentInstructionRegister</span> <span class="p">=</span> <span class="n">MemoryDataRegister</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">ProgramCounter</span> <span class="p">+=</span> <span class="m">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">PrintInstruction</span><span class="p">(</span><span class="n">OpCode</span> <span class="n">opcode</span><span class="p">,</span> <span class="n">CPU</span> <span class="n">cpu</span><span class="p">,</span> <span class="n">MainMemory</span> <span class="n">memory</span><span class="p">,</span> <span class="n">IODevice</span> <span class="n">ioDevice</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(!</span><span class="n">_debug</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="k">return</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">$&#34;#{ProgramCounter:X3} A:{cpu.ALU.Accumulator:X3} ({cpu.ALU.Accumulator:D3}) -&gt; {opcode.ToString()} {MemoryAddressRegister:X3} {MemoryDataRegister:X3}&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">bool</span> <span class="n">ExecuteInstruction</span><span class="p">(</span><span class="n">CPU</span> <span class="n">cpu</span><span class="p">,</span> <span class="n">MainMemory</span> <span class="n">memory</span><span class="p">,</span> <span class="n">IODevice</span> <span class="n">ioDevice</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="n">instruction</span> <span class="p">=</span> <span class="p">(</span><span class="n">OpCode</span><span class="p">)</span><span class="n">CurrentInstructionRegister</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        
</span></span><span class="line"><span class="cl">        <span class="n">PrintInstruction</span><span class="p">(</span><span class="n">instruction</span><span class="p">,</span> <span class="n">cpu</span><span class="p">,</span> <span class="n">memory</span><span class="p">,</span> <span class="n">ioDevice</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">switch</span> <span class="p">(</span><span class="n">instruction</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">HLT</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">$&#34;HALT encountered at address {ProgramCounter:X2}&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">LDA</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">MemoryAddressRegister</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">ProgramCounter</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="n">MemoryDataRegister</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">MemoryAddressRegister</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="n">cpu</span><span class="p">.</span><span class="n">ALU</span><span class="p">.</span><span class="n">Accumulator</span> <span class="p">=</span> <span class="n">MemoryDataRegister</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                
</span></span><span class="line"><span class="cl">                <span class="n">ProgramCounter</span> <span class="p">+=</span> <span class="m">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">LDI</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">MemoryAddressRegister</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">ProgramCounter</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="n">MemoryAddressRegister</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">MemoryAddressRegister</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="n">MemoryDataRegister</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">MemoryAddressRegister</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="n">cpu</span><span class="p">.</span><span class="n">ALU</span><span class="p">.</span><span class="n">Accumulator</span> <span class="p">=</span> <span class="n">MemoryDataRegister</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                
</span></span><span class="line"><span class="cl">                <span class="n">ProgramCounter</span> <span class="p">+=</span> <span class="m">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">STA</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">MemoryAddressRegister</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">ProgramCounter</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="n">MemoryDataRegister</span> <span class="p">=</span> <span class="n">cpu</span><span class="p">.</span><span class="n">ALU</span><span class="p">.</span><span class="n">Accumulator</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="n">memory</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="n">MemoryAddressRegister</span><span class="p">,</span> <span class="n">MemoryDataRegister</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">ProgramCounter</span> <span class="p">+=</span> <span class="m">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">INP</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">cpu</span><span class="p">.</span><span class="n">ALU</span><span class="p">.</span><span class="n">Accumulator</span> <span class="p">=</span> <span class="n">ioDevice</span><span class="p">.</span><span class="n">InputData</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">                <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">OUT</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">ioDevice</span><span class="p">.</span><span class="n">OutputData</span><span class="p">(</span><span class="n">cpu</span><span class="p">.</span><span class="n">ALU</span><span class="p">.</span><span class="n">Accumulator</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">MEM</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">MemoryAddressRegister</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">ProgramCounter</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">for</span> <span class="p">(</span><span class="kt">var</span> <span class="n">i</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">i</span> <span class="p">&lt;</span> <span class="n">cpu</span><span class="p">.</span><span class="n">ALU</span><span class="p">.</span><span class="n">Accumulator</span><span class="p">;</span> <span class="n">i</span><span class="p">++)</span>
</span></span><span class="line"><span class="cl">                <span class="p">{</span>
</span></span><span class="line"><span class="cl">                    <span class="kt">var</span> <span class="n">data</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">MemoryAddressRegister</span> <span class="p">+</span> <span class="n">i</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                    <span class="n">ioDevice</span><span class="p">.</span><span class="n">OutputData</span><span class="p">(</span><span class="n">data</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">ProgramCounter</span><span class="p">++;</span>
</span></span><span class="line"><span class="cl">                <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">ADD</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">MemoryAddressRegister</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">ProgramCounter</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="n">MemoryDataRegister</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">MemoryAddressRegister</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="n">cpu</span><span class="p">.</span><span class="n">ALU</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">MemoryDataRegister</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">ProgramCounter</span> <span class="p">+=</span> <span class="m">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">SUB</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">MemoryAddressRegister</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">ProgramCounter</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="n">MemoryDataRegister</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">MemoryAddressRegister</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="n">cpu</span><span class="p">.</span><span class="n">ALU</span><span class="p">.</span><span class="n">Subtract</span><span class="p">(</span><span class="n">MemoryDataRegister</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                
</span></span><span class="line"><span class="cl">                <span class="n">ProgramCounter</span> <span class="p">+=</span> <span class="m">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">CMP</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">MemoryAddressRegister</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">ProgramCounter</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="n">MemoryDataRegister</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">MemoryAddressRegister</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="n">cpu</span><span class="p">.</span><span class="n">ALU</span><span class="p">.</span><span class="n">Compare</span><span class="p">(</span><span class="n">MemoryDataRegister</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                
</span></span><span class="line"><span class="cl">                <span class="n">ProgramCounter</span> <span class="p">+=</span> <span class="m">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">MOV</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="kt">var</span> <span class="k">value</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">ProgramCounter</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="n">cpu</span><span class="p">.</span><span class="n">ALU</span><span class="p">.</span><span class="n">Accumulator</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="n">PrintInstruction</span><span class="p">(</span><span class="n">instruction</span><span class="p">,</span> <span class="n">cpu</span><span class="p">,</span> <span class="n">memory</span><span class="p">,</span> <span class="n">ioDevice</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                
</span></span><span class="line"><span class="cl">                <span class="n">ProgramCounter</span> <span class="p">+=</span> <span class="m">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">INC</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">cpu</span><span class="p">.</span><span class="n">ALU</span><span class="p">.</span><span class="n">Accumulator</span> <span class="p">+=</span> <span class="m">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">DEC</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">cpu</span><span class="p">.</span><span class="n">ALU</span><span class="p">.</span><span class="n">Accumulator</span> <span class="p">-=</span> <span class="m">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">JMP</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="kt">var</span> <span class="n">targetAddress</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">ProgramCounter</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                
</span></span><span class="line"><span class="cl">                <span class="n">ProgramCounter</span> <span class="p">=</span> <span class="n">targetAddress</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">case</span> <span class="n">OpCode</span><span class="p">.</span><span class="n">JZ</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">targetAddress</span> <span class="p">=</span> <span class="n">memory</span><span class="p">.</span><span class="n">Read</span><span class="p">(</span><span class="n">ProgramCounter</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">if</span> <span class="p">(</span><span class="n">cpu</span><span class="p">.</span><span class="n">ALU</span><span class="p">.</span><span class="n">Accumulator</span> <span class="p">==</span> <span class="m">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                    <span class="n">ProgramCounter</span> <span class="p">=</span> <span class="n">targetAddress</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">                <span class="k">else</span>
</span></span><span class="line"><span class="cl">                    <span class="n">ProgramCounter</span> <span class="p">+=</span> <span class="m">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="k">break</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="k">default</span><span class="p">:</span>
</span></span><span class="line"><span class="cl">                <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">$&#34;Unsupported instruction: {instruction} -&gt; HALT&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="k">return</span> <span class="kc">false</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ALU</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">Accumulator</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">ALU</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Accumulator</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Add</span><span class="p">(</span><span class="kt">int</span> <span class="n">b</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Accumulator</span> <span class="p">+=</span> <span class="n">b</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Subtract</span><span class="p">(</span><span class="kt">int</span> <span class="n">b</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Accumulator</span> <span class="p">-=</span> <span class="n">b</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Compare</span><span class="p">(</span><span class="kt">int</span> <span class="n">b</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Accumulator</span> <span class="p">=</span> <span class="p">(</span><span class="n">Accumulator</span> <span class="p">-</span> <span class="n">b</span><span class="p">)</span> <span class="p">==</span> <span class="m">0</span> <span class="p">?</span> <span class="m">0</span> <span class="p">:</span> <span class="m">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CPU</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">ControlUnit</span> <span class="n">ControlUnit</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">ALU</span> <span class="n">ALU</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">CPU</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">ControlUnit</span> <span class="p">=</span> <span class="k">new</span> <span class="n">ControlUnit</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">ALU</span> <span class="p">=</span> <span class="k">new</span> <span class="n">ALU</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Run</span><span class="p">(</span><span class="n">MainMemory</span> <span class="n">memory</span><span class="p">,</span> <span class="n">IODevice</span> <span class="n">ioDevice</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="n">running</span> <span class="p">=</span> <span class="kc">true</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">while</span> <span class="p">(</span><span class="n">running</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">ControlUnit</span><span class="p">.</span><span class="n">FetchInstruction</span><span class="p">(</span><span class="n">memory</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="n">running</span> <span class="p">=</span> <span class="n">ControlUnit</span><span class="p">.</span><span class="n">ExecuteInstruction</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="n">memory</span><span class="p">,</span> <span class="n">ioDevice</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">MainMemory</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span><span class="p">[]</span> <span class="n">Memory</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">MainMemory</span><span class="p">(</span><span class="kt">int</span> <span class="n">size</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Memory</span> <span class="p">=</span> <span class="k">new</span> <span class="kt">int</span><span class="p">[</span><span class="n">size</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">Read</span><span class="p">(</span><span class="kt">int</span> <span class="n">address</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">Memory</span><span class="p">[</span><span class="n">address</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Write</span><span class="p">(</span><span class="kt">int</span> <span class="n">address</span><span class="p">,</span> <span class="kt">int</span> <span class="k">value</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Memory</span><span class="p">[</span><span class="n">address</span><span class="p">]</span> <span class="p">=</span> <span class="k">value</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">IODevice</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">InputData</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="m">42</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">OutputData</span><span class="p">(</span><span class="kt">int</span> <span class="n">data</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">$&#34;Output: {data}&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Computer</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">CPU</span> <span class="n">Cpu</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">MainMemory</span> <span class="n">Memory</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">IODevice</span> <span class="n">IoDevice</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">Dictionary</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">,</span> <span class="kt">int</span><span class="p">&gt;</span> <span class="n">Labels</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="kt">int</span> <span class="n">Offset</span> <span class="p">{</span> <span class="k">get</span><span class="p">;</span> <span class="k">set</span><span class="p">;</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">Computer</span><span class="p">(</span><span class="kt">int</span> <span class="n">memorySize</span><span class="p">,</span> <span class="n">IODevice</span> <span class="n">ioDevice</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Cpu</span> <span class="p">=</span> <span class="k">new</span> <span class="n">CPU</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">        <span class="n">Memory</span> <span class="p">=</span> <span class="k">new</span> <span class="n">MainMemory</span><span class="p">(</span><span class="n">memorySize</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">IoDevice</span> <span class="p">=</span> <span class="n">ioDevice</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">Labels</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Dictionary</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">,</span> <span class="kt">int</span><span class="p">&gt;();</span>
</span></span><span class="line"><span class="cl">        <span class="n">Offset</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">LoadProgram</span><span class="p">(</span><span class="n">List</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">program</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="p">(</span><span class="kt">var</span> <span class="n">i</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">i</span> <span class="p">&lt;</span> <span class="n">program</span><span class="p">.</span><span class="n">Count</span><span class="p">;</span> <span class="n">i</span><span class="p">++)</span>
</span></span><span class="line"><span class="cl">            <span class="n">Memory</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="n">i</span><span class="p">,</span> <span class="n">program</span><span class="p">[</span><span class="n">i</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&#34;Program loaded into memory&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="k">void</span> <span class="n">Run</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&#34;Running program...&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">Cpu</span><span class="p">.</span><span class="n">Run</span><span class="p">(</span><span class="n">Memory</span><span class="p">,</span> <span class="n">IoDevice</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Compiler</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="k">readonly</span> <span class="n">Dictionary</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">,</span> <span class="kt">int</span><span class="p">&gt;</span> <span class="n">_labels</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kd">static</span> <span class="k">readonly</span> <span class="n">Regex</span> <span class="n">LabelRegex</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Regex</span><span class="p">(</span><span class="s">@&#34;\s*:\s*(\w+)&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">Compiler</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">_labels</span> <span class="p">=</span> <span class="k">new</span> <span class="n">Dictionary</span><span class="p">&lt;</span><span class="kt">string</span><span class="p">,</span> <span class="kt">int</span><span class="p">&gt;();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kd">static</span> <span class="kt">string</span> <span class="n">RemoveComment</span><span class="p">(</span><span class="kt">string</span> <span class="n">line</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="n">commentIndex</span> <span class="p">=</span> <span class="n">line</span><span class="p">.</span><span class="n">IndexOf</span><span class="p">(</span><span class="sc">&#39;#&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">commentIndex</span> <span class="p">!=</span> <span class="p">-</span><span class="m">1</span> <span class="p">?</span> <span class="n">line</span><span class="p">.</span><span class="n">Substring</span><span class="p">(</span><span class="m">0</span><span class="p">,</span> <span class="n">commentIndex</span><span class="p">).</span><span class="n">Trim</span><span class="p">()</span> <span class="p">:</span> <span class="n">line</span><span class="p">.</span><span class="n">Trim</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kt">int</span> <span class="n">ParseOperand</span><span class="p">(</span><span class="kt">string</span> <span class="n">token</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kt">int</span> <span class="n">operand</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">token</span><span class="p">.</span><span class="n">StartsWith</span><span class="p">(</span><span class="s">&#34;@&#34;</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="kt">var</span> <span class="n">label</span> <span class="p">=</span> <span class="n">token</span><span class="p">.</span><span class="n">Substring</span><span class="p">(</span><span class="m">1</span><span class="p">,</span> <span class="n">token</span><span class="p">.</span><span class="n">Length</span> <span class="p">-</span> <span class="m">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">_labels</span><span class="p">.</span><span class="n">ContainsKey</span><span class="p">(</span><span class="n">label</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">                <span class="n">operand</span> <span class="p">=</span> <span class="n">_labels</span><span class="p">[</span><span class="n">label</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">            <span class="k">else</span>
</span></span><span class="line"><span class="cl">                <span class="k">throw</span> <span class="k">new</span> <span class="n">NotSupportedException</span><span class="p">(</span><span class="s">$&#34;Label not found: {token}&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="k">else</span>
</span></span><span class="line"><span class="cl">            <span class="k">try</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">operand</span> <span class="p">=</span> <span class="kt">int</span><span class="p">.</span><span class="n">Parse</span><span class="p">(</span><span class="n">token</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="k">catch</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="k">throw</span> <span class="k">new</span> <span class="n">NotSupportedException</span><span class="p">(</span><span class="s">$&#34;Unknown token: {token}&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">operand</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">public</span> <span class="n">List</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">Compile</span><span class="p">(</span><span class="kt">string</span> <span class="n">sourceCode</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="n">compiledProgram</span> <span class="p">=</span> <span class="k">new</span> <span class="n">List</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;();</span>
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="n">lines</span> <span class="p">=</span> <span class="n">sourceCode</span><span class="p">.</span><span class="n">Split</span><span class="p">(</span><span class="k">new</span><span class="p">[]</span> <span class="p">{</span> <span class="n">Environment</span><span class="p">.</span><span class="n">NewLine</span> <span class="p">},</span> <span class="n">StringSplitOptions</span><span class="p">.</span><span class="n">RemoveEmptyEntries</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1">// First pass - process labels</span>
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="n">offset</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="n">index</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">line</span> <span class="k">in</span> <span class="n">lines</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="kt">var</span> <span class="n">trimmedLine</span> <span class="p">=</span> <span class="n">RemoveComment</span><span class="p">(</span><span class="n">line</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">trimmedLine</span><span class="p">.</span><span class="n">Length</span> <span class="p">==</span> <span class="m">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="k">continue</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="kt">var</span> <span class="n">match</span> <span class="p">=</span> <span class="n">LabelRegex</span><span class="p">.</span><span class="n">Match</span><span class="p">(</span><span class="n">trimmedLine</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">match</span><span class="p">.</span><span class="n">Success</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">_labels</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">match</span><span class="p">.</span><span class="n">Groups</span><span class="p">[</span><span class="m">1</span><span class="p">].</span><span class="n">Value</span><span class="p">,</span> <span class="n">index</span> <span class="p">-</span> <span class="n">offset</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">                <span class="n">offset</span><span class="p">++;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="kt">var</span> <span class="n">tokens</span> <span class="p">=</span> <span class="n">trimmedLine</span><span class="p">.</span><span class="n">Split</span><span class="p">(</span><span class="sc">&#39; &#39;</span><span class="p">,</span> <span class="n">StringSplitOptions</span><span class="p">.</span><span class="n">RemoveEmptyEntries</span> <span class="p">|</span> <span class="n">StringSplitOptions</span><span class="p">.</span><span class="n">TrimEntries</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="n">index</span> <span class="p">+=</span> <span class="n">tokens</span><span class="p">.</span><span class="n">Length</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="c1">// Second pass - compile instructions</span>
</span></span><span class="line"><span class="cl">        <span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">line</span> <span class="k">in</span> <span class="n">lines</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="kt">var</span> <span class="n">trimmedLine</span> <span class="p">=</span> <span class="n">RemoveComment</span><span class="p">(</span><span class="n">line</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">trimmedLine</span><span class="p">.</span><span class="n">Length</span> <span class="p">==</span> <span class="m">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">                <span class="k">continue</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">trimmedLine</span><span class="p">.</span><span class="n">StartsWith</span><span class="p">(</span><span class="sc">&#39;:&#39;</span><span class="p">))</span> 
</span></span><span class="line"><span class="cl">                <span class="k">continue</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="kt">var</span> <span class="n">operand</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="kt">var</span> <span class="n">tokens</span> <span class="p">=</span> <span class="n">trimmedLine</span><span class="p">.</span><span class="n">Split</span><span class="p">(</span><span class="sc">&#39; &#39;</span><span class="p">,</span> <span class="n">StringSplitOptions</span><span class="p">.</span><span class="n">RemoveEmptyEntries</span> <span class="p">|</span> <span class="n">StringSplitOptions</span><span class="p">.</span><span class="n">TrimEntries</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">            <span class="k">if</span> <span class="p">(</span><span class="n">Enum</span><span class="p">.</span><span class="n">TryParse</span><span class="p">(</span><span class="n">tokens</span><span class="p">[</span><span class="m">0</span><span class="p">].</span><span class="n">ToUpper</span><span class="p">(),</span> <span class="k">out</span> <span class="n">OpCode</span> <span class="n">opCode</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="n">compiledProgram</span><span class="p">.</span><span class="n">Add</span><span class="p">((</span><span class="kt">int</span><span class="p">)</span><span class="n">opCode</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="k">if</span> <span class="p">(</span><span class="n">tokens</span><span class="p">.</span><span class="n">Length</span> <span class="p">&lt;=</span> <span class="m">1</span><span class="p">)</span> 
</span></span><span class="line"><span class="cl">                    <span class="k">continue</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">                <span class="n">operand</span> <span class="p">=</span> <span class="n">ParseOperand</span><span class="p">(</span><span class="n">tokens</span><span class="p">[</span><span class="m">1</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">                <span class="n">compiledProgram</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">operand</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">            <span class="k">else</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">                <span class="c1">// try to convert to a number</span>
</span></span><span class="line"><span class="cl">                <span class="n">operand</span> <span class="p">=</span> <span class="n">ParseOperand</span><span class="p">(</span><span class="n">tokens</span><span class="p">[</span><span class="m">0</span><span class="p">]);</span>
</span></span><span class="line"><span class="cl">                <span class="n">compiledProgram</span><span class="p">.</span><span class="n">Add</span><span class="p">(</span><span class="n">operand</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">DumpByteCode</span><span class="p">(</span><span class="n">compiledProgram</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">return</span> <span class="n">compiledProgram</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kd">private</span> <span class="kd">static</span> <span class="k">void</span> <span class="n">DumpByteCode</span><span class="p">(</span><span class="n">List</span><span class="p">&lt;</span><span class="kt">int</span><span class="p">&gt;</span> <span class="n">compiledProgram</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&#34;Compiled byte-code:&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="kt">var</span> <span class="n">separator</span> <span class="p">=</span> <span class="s">&#34;\n&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="k">for</span> <span class="p">(</span><span class="kt">var</span> <span class="n">index</span> <span class="p">=</span> <span class="m">0</span><span class="p">;</span> <span class="n">index</span> <span class="p">&lt;</span> <span class="n">compiledProgram</span><span class="p">.</span><span class="n">Count</span><span class="p">;</span> <span class="n">index</span><span class="p">++)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">Console</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="s">$&#34;{index:X2}|&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="n">separator</span> <span class="p">+=</span> <span class="s">&#34;--|&#34;</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="n">separator</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="k">foreach</span> <span class="p">(</span><span class="kt">var</span> <span class="n">op</span> <span class="k">in</span> <span class="n">compiledProgram</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">            <span class="n">Console</span><span class="p">.</span><span class="n">Write</span><span class="p">(</span><span class="s">$&#34;{op:X2}|&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">Console</span><span class="p">.</span><span class="n">WriteLine</span><span class="p">(</span><span class="s">&#34;\n&#34;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><h1 id="analiza-cyklu-rozkazowego">Analiza cyklu rozkazowego</h1>
<h2 id="zdefiniowanie-cyklu-rozkazowego-i-jego-faz-pobieranie-dekodowanie-wykonanie-dostęp-do-pamięci-i-zapis-wyniku">Zdefiniowanie cyklu rozkazowego i jego faz (pobieranie, dekodowanie, wykonanie, dostęp do pamięci i zapis wyniku).</h2>
<p>Cykl rozkazowy to sekwencja kroków, które wykonuje procesor w celu pobrania, zdekodowania i wykonania pojedynczego rozkazu. Cykl rozkazowy składa się z pięciu głównych faz, które są realizowane sekwencyjnie:</p>
<ol>
<li>
<p>Pobieranie (Fetch): W tej fazie procesor pobiera rozkaz z pamięci. Wartość licznika rozkazów (Program Counter, PC) wskazuje na adres pamięci, z którego rozkaz ma być pobrany. Po pobraniu rozkazu, licznik rozkazów jest zwiększany o rozmiar rozkazu, aby wskazać na kolejny rozkaz.</p>
</li>
<li>
<p>Dekodowanie (Decode): Pobrany rozkaz jest dekodowany przez jednostkę dekodującą procesora, która interpretuje go i ustala, jakie operacje należy wykonać oraz które rejestry i/lub wartości są używane jako argumenty.</p>
</li>
<li>
<p>Wykonanie (Execute): W tej fazie jednostka wykonawcza procesora przeprowadza operacje zdefiniowane przez rozkaz. Może to obejmować działania arytmetyczne, logiczne, przesunięcia bitowe lub inne operacje. Wynik tych operacji jest przechowywany w rejestrze tymczasowym.</p>
</li>
<li>
<p>Dostęp do pamięci (Memory Access): Jeśli rozkaz wymaga dostępu do pamięci, na przykład w celu odczytania lub zapisania wartości, w tej fazie procesor odczytuje dane z pamięci lub zapisuje je w odpowiednim miejscu.</p>
</li>
<li>
<p>Zapis wyniku (Write-back): W tej ostatniej fazie wynik operacji, przechowywany w rejestrze tymczasowym, jest zapisywany do odpowiedniego rejestru procesora lub do pamięci, jeśli jest to wymagane.</p>
</li>
</ol>
<p>Przykład analizy cyklu rozkazowego:</p>
<p>Rozważmy prosty przykład dodawania dwóch liczb, przechowywanych w rejestrach R1 i R2, a wynik ma być zapisany w rejestrze R3. Rozkaz może wyglądać tak: ADD R3, R1, R2</p>
<ol>
<li>Pobieranie: Procesor pobiera rozkaz ADD z adresu wskazanego przez licznik rozkazów (PC) i zwiększa wartość PC.</li>
<li>Dekodowanie: Jednostka dekodująca interpretuje rozkaz jako operację dodawania, gdzie R1 i R2 są argumentami, a wynik ma być zapisany w R3.</li>
<li>Wykonanie: Jednostka wykonawcza dodaje wartości z rejestru R1 i R2, a wynik przechowuje w rejestrze tymczasowym.</li>
<li>Dostęp do pamięci: W tym przypadku nie ma potrzeby dostępu do pamięci, ponieważ wszystkie wartości są przechowywane w rejestrach.</li>
<li>Zapis wyniku: Wynik dodawania, przechowywany w rejestrze tymczasow</li>
</ol>
<h2 id="etapy-cyklu-rozkazowego">Etapy cyklu rozkazowego.</h2>
<p>Przyjmijmy prosty zestaw rozkazów oparty na hipotetycznym procesorze z ograniczoną architekturą. Rozkazy:</p>
<ol>
<li>LOAD R1, (ADDR) - Ładuje wartość z pamięci o adresie ADDR do rejestru R1.</li>
<li>STORE (ADDR), R1 - Zapisuje wartość z rejestru R1 do pamięci o adresie ADDR.</li>
<li>ADD R1, R2 - Dodaje wartości z rejestru R1 i R2, a wynik zapisuje w rejestrze R1.</li>
<li>SUB R1, R2 - Odejmuje wartość rejestru R2 od wartości rejestru R1, a wynik zapisuje w rejestrze R1.</li>
<li>JUMP ADDR - Bezwarunkowy skok do adresu ADDR.</li>
<li>JNZERO R1, ADDR - Skok warunkowy do względnego adresu ADDR, jeśli wartość w rejestrze R1 jest różna od 0.</li>
</ol>
<p>Omówienie poszczególnych etapów cyklu rozkazowego dla każdego z rozkazów:</p>
<ol>
<li>
<p>LOAD R1, (ADDR):</p>
<ul>
<li>Pobieranie: Procesor pobiera rozkaz LOAD z pamięci.</li>
<li>Dekodowanie: Dekodowanie rozkazu LOAD i identyfikacja rejestru R1 oraz adresu pamięci ADDR.</li>
<li>Wykonanie: Brak operacji wykonawczych dla tego rozkazu.</li>
<li>Dostęp do pamięci: Odczyt wartości z pamięci o adresie ADDR.</li>
<li>Zapis wyniku: Zapisanie odczytanej wartości do rejestru R1.</li>
</ul>
</li>
<li>
<p>STORE (ADDR), R1:</p>
<ul>
<li>Pobieranie: Procesor pobiera rozkaz STORE z pamięci.</li>
<li>Dekodowanie: Dekodowanie rozkazu STORE i identyfikacja rejestru R1 oraz adresu pamięci ADDR.</li>
<li>Wykonanie: Brak operacji wykonawczych dla tego rozkazu.</li>
<li>Dostęp do pamięci: Zapis wartości z rejestru R1 do pamięci o adresie ADDR.</li>
<li>Zapis wyniku: Brak operacji zapisu wyniku, ponieważ wynik został już zapisany w pamięci.</li>
</ul>
</li>
<li>
<p>ADD R1, R2:</p>
<ul>
<li>Pobieranie: Procesor pobiera rozkaz ADD z pamięci.</li>
<li>Dekodowanie: Dekodowanie rozkazu ADD i identyfikacja rejestrów R1 i R2.</li>
<li>Wykonanie: Dodawanie wartości z rejestru R1 i R2, a wynik przechowuje w rejestrze tymczasowym.</li>
<li>Dostęp do pamięci: Brak dostępu do pamięci, ponieważ wszystkie wartości są przechowywane w rejestrach.</li>
<li>Zapis wyniku: Zapisanie wyniku dodawania do rejestru R1.</li>
</ul>
</li>
<li>
<p>SUB R1, R2:</p>
<ul>
<li>Pobieranie: Procesor pobiera rozkaz SUB z pamięci.</li>
<li>Dekodowanie: Dekodowanie rozkazu SUB i identyfikacja rejestrów R1 i R2.</li>
<li>Wykonanie: Odejmowanie wartości rejestru R2 od wartości rejestru R1, a wynik przechowuje w rejestrze tymczasowym.</li>
<li>Dostęp do pamięci: Brak dostępu do pamięci, ponieważ wszystkie wartości są przechowywane w rejestrach.</li>
<li>Zapis wyniku: Zapisanie wyniku odejmowania do rejestru R1.</li>
</ul>
</li>
<li>
<p>JUMP ADDR:</p>
<ul>
<li>Pobieranie: Procesor pobiera rozkaz JUMP z pamięci.</li>
<li>Dekodowanie: Dekodowanie rozkazu JUMP i identyfikacja adresu ADDR.</li>
<li>Wykonanie: Aktualizacja licznika rozkazów (PC) na wartość ADDR.</li>
<li>Dostęp do pamięci: Brak dostępu do pamięci.</li>
<li>Zapis wyniku: Brak operacji zapisu wyniku, ponieważ wynik został już zaktualizowany w liczniku rozkazów (PC).</li>
</ul>
</li>
<li>
<p>JNZERO R1, ADDR:</p>
<ul>
<li>Pobieranie: Procesor pobiera rozkaz JZERO z pamięci.</li>
<li>Dekodowanie: Dekodowanie rozkazu JZERO i identyfikacja rejestru R1 oraz adresu ADDR.</li>
<li>Wykonanie: Sprawdzenie, czy wartość w rejestrze R1 wynosi 0.</li>
<li>Dostęp do pamięci: Brak dostępu do pamięci.</li>
<li>Zapis wyniku: Jeśli wartość w rejestrze R1 wynosi 0, aktualizacja licznika rozkazów (PC) o wartość ADDR. W przeciwnym razie PC zostaje zwiększone do kolejnego rozkazu.</li>
</ul>
</li>
</ol>
<p>Dla każdego z tych rozkazów analiza cyklu rozkazowego obejmuje omówienie poszczególnych faz (pobieranie, dekodowanie, wykonanie, dostęp do pamięci i zapis wyniku) oraz zrozumienie, jak procesor wykonuje te rozkazy sekwencyjnie. W przypadku procesorów z potokiem rozkazowym, kolejne rozkazy mogą być przetwarzane równocześnie w różnych fazach, zwiększając przepustowość procesora i efektywnie przyspieszając wykonywanie programu.</p>
<h2 id="prosty-symulator-cyklu-rozkazowego">Prosty symulator cyklu rozkazowego</h2>
<p><strong>Lab_06:</strong></p>
<p>Ćwiczenie:</p>
<ol>
<li>Proszę uruchomić pierwszy program: Lab_06_a</li>
<li>Proszę opisać kolejne cykle rozkazowe, jakie wykonuje procesor</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">memory = [10, 6, 7, 2, 1, 0, 0]
</span></span><span class="line"><span class="cl">instructions = [
</span></span><span class="line"><span class="cl">    (&#34;LOAD&#34;,  0, 0),
</span></span><span class="line"><span class="cl">    (&#34;LOAD&#34;,  1, 2),
</span></span><span class="line"><span class="cl">    (&#34;ADD&#34;,   0, 1),
</span></span><span class="line"><span class="cl">    (&#34;STORE&#34;, 0, 0),
</span></span><span class="line"><span class="cl">]
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="3">
<li>Proszę uruchomić drugi program:  Lab_06_b</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">memory = [10, 6, 7, 2, 1, 0, 0]
</span></span><span class="line"><span class="cl">instructions = [
</span></span><span class="line"><span class="cl">    (&#34;LOAD&#34;,  0, 0),
</span></span><span class="line"><span class="cl">    (&#34;LOAD&#34;,  1, 2),
</span></span><span class="line"><span class="cl">    (&#34;ADD&#34;,   0, 1),
</span></span><span class="line"><span class="cl">    (&#34;STORE&#34;, 0, 0),
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    (&#34;LOAD&#34;,  3, 1),
</span></span><span class="line"><span class="cl">    (&#34;LOAD&#34;,  2, 3),
</span></span><span class="line"><span class="cl">    (&#34;SUB&#34;,   3, 2),
</span></span><span class="line"><span class="cl">    (&#34;STORE&#34;, 1, 3),
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    (&#34;JNZERO&#34;, 3, -9),
</span></span><span class="line"><span class="cl">]
</span></span></code></pre></td></tr></table>
</div>
</div><ol start="4">
<li>Proszę opisać cykle rozkazowe dla ostatniej instrukcji.</li>
<li>Jakie jest działa drugi program? Proszę opisać.</li>
</ol>
<h1 id="analiza-potoku-rozkazowego">Analiza potoku rozkazowego:</h1>
<h2 id="potok-rozkazowego-i-jego-cele-zwiększenie-przepustowości-równoległe-wykonanie-rozkazów">Potok rozkazowego i jego cele (zwiększenie przepustowości, równoległe wykonanie rozkazów).</h2>
<p>Potok rozkazowy (ang. instruction pipeline) to technika wykorzystywana w mikroarchitekturze procesorów, mająca na celu zwiększenie przepustowości i wydajności przez równoczesne wykonywanie kilku rozkazów w różnych etapach ich przetwarzania. Potok rozkazowy dzieli cykl rozkazowy na kilka etapów, z których każdy może być przetwarzany równocześnie przez różne jednostki wykonawcze procesora. Dzięki temu, zamiast czekać na zakończenie jednego rozkazu, procesor może przetwarzać kolejne rozkazy, zwiększając przepustowość i efektywnie przyspieszając wykonywanie programu.</p>
<h3 id="cele-potoku-rozkazowego">Cele potoku rozkazowego:</h3>
<ol>
<li>
<p>Zwiększenie przepustowości: Potok rozkazowy pozwala na równoczesne przetwarzanie kilku rozkazów w różnych etapach cyklu rozkazowego, co zwiększa przepustowość procesora i pozwala na szybsze wykonanie programu.</p>
</li>
<li>
<p>Równoległe wykonanie rozkazów: Potok rozkazowy pozwala na równoczesne wykonywanie różnych operacji w różnych jednostkach wykonawczych procesora, co oznacza, że procesor może jednocześnie wykonywać operacje na różnych danych, zwiększając wydajność obliczeń.</p>
</li>
</ol>
<h3 id="przykład-potoku-rozkazowego">Przykład potoku rozkazowego</h3>
<p>Załóżmy, że mamy prosty procesor z czterema etapami cyklu rozkazowego: pobieranie (IF - Instruction Fetch), dekodowanie (ID - Instruction Decode), wykonanie (EX - Execute) i zapis wyniku (WB - Write Back). Potok rozkazowy dla tego procesora będzie miał cztery etapy, które można wykonać równocześnie dla różnych rozkazów.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-as" data-lang="as"><span class="line"><span class="cl">  <span class="nx">Rozkaz</span> <span class="mi">1</span><span class="o">:</span> <span class="nx">IF</span> <span class="o">-&gt;</span> <span class="nx">ID</span> <span class="o">-&gt;</span> <span class="nx">EX</span> <span class="o">-&gt;</span> <span class="nx">WB</span>
</span></span><span class="line"><span class="cl">  <span class="nx">Rozkaz</span> <span class="mi">2</span><span class="o">:</span>    <span class="o">-&gt;</span> <span class="nx">IF</span> <span class="o">-&gt;</span> <span class="nx">ID</span> <span class="o">-&gt;</span> <span class="nx">EX</span> <span class="o">-&gt;</span> <span class="nx">WB</span>
</span></span><span class="line"><span class="cl">  <span class="nx">Rozkaz</span> <span class="mi">3</span><span class="o">:</span>          <span class="o">-&gt;</span> <span class="nx">IF</span> <span class="o">-&gt;</span> <span class="nx">ID</span> <span class="o">-&gt;</span> <span class="nx">EX</span> <span class="o">-&gt;</span> <span class="nx">WB</span>
</span></span><span class="line"><span class="cl">  <span class="nx">Rozkaz</span> <span class="mi">4</span><span class="o">:</span>                <span class="o">-&gt;</span> <span class="nx">IF</span> <span class="o">-&gt;</span> <span class="nx">ID</span> <span class="o">-&gt;</span> <span class="nx">EX</span> <span class="o">-&gt;</span> <span class="nx">WB</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>Jak widać na powyższym przykładzie, potok rozkazowy pozwala na równoczesne przetwarzanie kilku rozkazów w różnych etapach cyklu rozkazowego. W momencie, gdy pierwszy rozkaz jest w fazie wykonania (EX), drugi rozkaz jest w fazie dekodowania (ID), a trzeci rozkaz jest pobierany (IF). Dzięki temu procesor może jednocześnie pracować nad różnymi rozkazami, zwiększając swoją przepustowość i wydajność.</p>
<p>Jednakże, potok rozkazowy wprowadza również pewne wyzwania, takie jak zarządzanie hazardami (ang. hazards). Hazardy to sytuacje, w których wynik jednego rozkazu jest potrzebny przez następny rozkaz, a potok rozkazowy musi zarządzać tymi zależnościami, aby uniknąć konflikty lub zależności.</p>
<p>Istnieją trzy główne rodzaje hazardów:</p>
<ol>
<li>
<p>Hazardy strukturalne: Występują, gdy różne rozkazy próbują jednocześnie korzystać z tego samego zasobu procesora, takiego jak jednostka wykonawcza, pamięć czy rejestry. Hazardy strukturalne mogą prowadzić do opóźnień lub konieczności oczekiwania przez niektóre rozkazy na dostęp do zasobów.</p>
<p>Sposoby minimalizowania hazardów strukturalnych:</p>
<ol>
<li>Wprowadzenie dodatkowych zasobów: Zwiększenie liczby jednostek wykonawczych, pamięci czy rejestrów może zmniejszyć ryzyko wystąpienia konfliktów.</li>
<li>Replikacja zasobów: Dodatkowe zasoby pozwalają na równoczesne korzystanie z nich przez różne rozkazy.</li>
<li>Wykorzystanie buforów i kolejkowania: Buforowanie i kolejkowanie operacji może pomóc w zarządzaniu dostępem do zasobów i zmniejszyć opóźnienia.</li>
</ol>
</li>
<li>
<p>Hazardy danych: Występują, gdy jeden rozkaz jest zależny od wyniku innego rozkazu, który jeszcze nie został zakończony. Hazardy danych mogą prowadzić do nieprawidłowych wyników, jeśli nie zostaną odpowiednio obsłużone.</p>
<p>Sposoby minimalizowania hazardów danych:</p>
<ol>
<li>Przesunięcie potoku (stalling): Wstrzymywanie wykonywania zależnego rozkazu aż do momentu, gdy wynik potrzebny dla tego rozkazu będzie dostępny.</li>
<li>Przekształcanie potoku (forwarding): Przekazanie wyniku zależnego rozkazu bezpośrednio do kolejnego rozkazu, bez konieczności zapisywania wyniku w rejestrze.</li>
<li>Przeplanowanie rozkazów: Kompilator lub procesor może próbować zmienić kolejność rozkazów, aby zmniejszyć zależności i poprawić wydajność potoku rozkazowego.</li>
</ol>
</li>
<li>
<p>Hazardy kontroli: Występują, gdy kolejność wykonywania rozkazów ulega zmianie z powodu instrukcji warunkowych, takich jak skoki czy instrukcje warunkowe. Hazardy kontroli mogą prowadzić do niepotrzebnego wypełnienia potoku rozkazów i straty wydajności.</p>
</li>
</ol>
<blockquote>
<p>Ref:</p>
<ul>
<li><a href="https://www.youtube.com/watch?v=aujUQ274bEE">Branch prediction examples</a></li>
</ul>
</blockquote>
<p>Sposoby minimalizowania hazardów kontroli:</p>
<ol>
<li>Przewidywanie rozgałęzień (branch prediction): Procesor próbuje przewidywać, czy dane rozgałęzienie zostanie wykonane, i wstępnie ładuje odpowiednie rozkazy do potoku rozkazowego.</li>
<li>Opóźnianie rozgałęzienia (branch delay slot): Procesor pozwala na wykonanie jednego lub kilku rozkazów po instrukcji rozgałęzienia, zanim rzeczywista zmiana przepływu sterowania zostanie wprowadzona. Kompilator może umieścić niezależne rozkazy w tych opóźnionych miejscach, aby zmniejszyć straty wydajności spowodowane hazardami kontroli.</li>
<li>Wykonanie spekulatywne (speculative execution): Procesor wykonuje obie ścieżki po rozgałęzieniu warunkowym, jednocześnie śledząc poprawność wyników. Gdy warunek rozgałęzienia zostanie ostatecznie wyznaczony, procesor odrzuca wyniki niewłaściwej ścieżki i kontynuuje wykonanie poprawnej ścieżki.</li>
</ol>
<blockquote>
<p>Ref:
Interesująca podatność związana z SE (side-channel) - <a href="https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)">Spectre - wiki</a>
<a href="https://spectreattack.com/spectre.pdf">Spectre Attacks: Exploiting Speculative Execution</a>
<a href="https://github.com/IAIK/meltdown">Meltdown Security Vulnerability</a>
<a href="https://www.geeksforgeeks.org/meltdown-security-vulnerability/">Meltdown Proof-of-Concept</a></p>
</blockquote>
<p>Podatność Spectre dotyczy złośliwego wykorzystania spekulatywnego wykonania instrukcji przez procesor w celu uzyskania dostępu do poufnych informacji.</p>
<p><strong>Przetwarzanie wielowątkowe (multithreading)</strong>: Procesor może przełączać się między różnymi wątkami wykonawczymi, gdy napotyka hazardy kontroli. Pozwala to na utrzymanie potoku rozkazowego aktywnym i wydajnym, nawet gdy jeden wątek oczekuje na wynik rozgałęzienia.</p>
<p>W praktyce zaawansowane mikroarchitektury procesorów stosują różne techniki, aby zarządzać hazardami potoku rozkazowego i zwiększać wydajność procesora. Optymalizacja wykorzystania potoku rozkazowego, zarządzanie hazardami oraz przyspieszenie wykonywania programów są kluczowe dla osiągnięcia wysokiej wydajności w nowoczesnych procesorach.</p>
<h2 id="przykładowe-sposoby-minimalizacji-hazardów">Przykładowe sposoby minimalizacji hazardów</h2>
<ol>
<li>Hazard strukturalny:
Załóżmy, że mamy procesor z jednym modułem ALU (Arithmetic Logic Unit) i poniższymi rozkazami do wykonania:</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Rozkaz 1: ADD R1, R2, R3
</span></span><span class="line"><span class="cl">Rozkaz 2: MUL R4, R5, R6
</span></span><span class="line"><span class="cl">Rozkaz 3: SUB R7, R8, R9
</span></span></code></pre></td></tr></table>
</div>
</div><p>Wszystkie trzy rozkazy wymagają dostępu do ALU. W celu zapobieżenia hazardom strukturalnym, procesor może:</p>
<ol>
<li>
<p>Wprowadzić dodatkowe moduły ALU, aby umożliwić równoczesne wykonywanie różnych operacji.</p>
</li>
<li>
<p>Zastosować buforowanie i kolejkowanie operacji, aby zarządzać dostępem do ALU i zmniejszyć opóźnienia.</p>
</li>
<li>
<p>Hazard danych:
Załóżmy, że mamy następujący ciąg rozkazów:</p>
</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Rozkaz 1: ADD R1, R2, R3
</span></span><span class="line"><span class="cl">Rozkaz 2: SUB R4, R1, R5
</span></span><span class="line"><span class="cl">Rozkaz 3: MUL R6, R4, R7
</span></span></code></pre></td></tr></table>
</div>
</div><p>Wynik rozkazu 1 (ADD) jest używany jako wejście dla rozkazu 2 (SUB), a wynik rozkazu 2 jest używany jako wejście dla rozkazu 3 (MUL). W celu zarządzania hazardami danych, procesor może:</p>
<ol>
<li>
<p>Wstrzymać wykonywanie rozkazu 2 (stalling), aż do momentu, gdy wynik rozkazu 1 będzie dostępny.</p>
</li>
<li>
<p>Zastosować przekształcanie potoku (forwarding), przekazując wynik rozkazu 1 bezpośrednio do rozkazu 2, bez konieczności zapisywania wyniku w rejestrze.</p>
</li>
<li>
<p>Hazard kontroli:
Załóżmy, że mamy następujący ciąg rozkazów z instrukcją warunkowego skoku:</p>
</li>
</ol>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-as" data-lang="as"><span class="line"><span class="cl"><span class="nx">Rozkaz_1</span><span class="o">:</span> <span class="nx">CMP</span> <span class="nx">R1</span><span class="o">,</span> <span class="nx">R2</span>
</span></span><span class="line"><span class="cl"><span class="nx">Rozkaz_2</span><span class="o">:</span> <span class="nx">JNE</span> <span class="nx">label</span>
</span></span><span class="line"><span class="cl"><span class="nx">Rozkaz_3</span><span class="o">:</span> <span class="nx">ADD</span> <span class="nx">R3</span><span class="o">,</span> <span class="nx">R4</span><span class="o">,</span> <span class="nx">R5</span>
</span></span><span class="line"><span class="cl"><span class="nx">label</span><span class="o">:</span>    <span class="nx">MUL</span> <span class="nx">R6</span><span class="o">,</span> <span class="nx">R7</span><span class="o">,</span> <span class="nx">R8</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>W przypadku hazardu kontroli spowodowanego przez instrukcję warunkowego skoku (JNE), procesor może:</p>
<ol>
<li>Zastosować przewidywanie rozgałęzień (branch prediction), próbując przewidzieć, czy skok zostanie wykonany, i wstępnie ładując odpowiednie rozkazy do potoku rozkazowego.</li>
<li>Wykorzystać opóźnienie rozgałęzienia (branch delay slot), umieszczając jeden lub więcej niezależnych rozkazów po instrukcji skoku, które zostaną wykonane przed rzeczywistym skokiem</li>
</ol>
<p>W praktyce, zaawansowane mikroarchitektury procesorów stosują różne techniki, aby zarządzać hazardami potoku rozkazowego i zwiększać wydajność procesora, takie jak przewidywanie rozgałęzień, optymalizacja wykonywania potoku czy wykorzystanie wielowątkowości.</p>
<h2 id="zadanie-z-symulacją-symulator-potoku-rozkazowego-dla-prostego-procesora-uwzględniając-hazardy">Zadanie z symulacją: symulator potoku rozkazowego dla prostego procesora, uwzględniając hazardy.</h2>
<h3 id="hazard-danych">Hazard danych</h3>
<p>Prosty procesor z potokiem rozkazowym o 4 etapach (IF - pobieranie rozkazu, ID - dekodowanie, EX - wykonanie, WB - zapis wyniku)</p>
<p><strong>Lab_07</strong></p>
<p>Powyższy symulator wykonuje sekwencję rozkazów (program) na prostym procesorze. Wprowadza wstrzymanie (stalling) potoku, gdy wykryje hazard danych, co pozwala na zaktualizowanie wartości rejestru przed przekazaniem go do kolejnego rozkazu. Symulator wyświetla etap potoku dla każdego rozkazu oraz numer cyklu. Po zakończeniu symulacji wyświetlane są końcowe wartości rejestrów procesora.</p>
<h3 id="hazard-kontroli">Hazard kontroli</h3>
<p>Symulator prostego procesora z uwzględnieniem hazardu kontroli (branch hazard). Procesor ten ma prosty potok rozkazów o pięciu etapach: pobieranie rozkazu (IF), dekodowanie (ID), wykonanie (EX), dostęp do pamięci (MEM) i zapis wyniku (WB).</p>
<p><strong>Lab_07</strong> + branch predictor</p>
<p>Symulator wykonuje sekwencję rozkazów na prostym procesorze z potokiem rozkazowym. Wprowadza wstrzymanie (stalling) potoku, gdy wykryje hazard kontroli (branch hazard), co pozwala na zaktualizowanie wartości PC przed pobraniem kolejnego rozkazu. Symulator wyświetla etap potoku dla każdego rozkazu oraz numer cyklu. Po zakończeniu symulacji wyświetlane są końcowe wartości rejestrów procesora.</p>
<h1 id="instruction-reordering">Instruction reordering</h1>
<p>Uwaga: Warto zauważyć, że efekty takie jak reordering instrukcji są zależne od architektury procesora, a w przypadku niektórych implementacji może być trudno uzyskać te efekty w sposób powtarzalny.</p>
<p>Oto prosty program w C++, który ilustruje reordering instrukcji na procesorze x86:</p>
<p><strong>Lab_10</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">  1
</span><span class="lnt">  2
</span><span class="lnt">  3
</span><span class="lnt">  4
</span><span class="lnt">  5
</span><span class="lnt">  6
</span><span class="lnt">  7
</span><span class="lnt">  8
</span><span class="lnt">  9
</span><span class="lnt"> 10
</span><span class="lnt"> 11
</span><span class="lnt"> 12
</span><span class="lnt"> 13
</span><span class="lnt"> 14
</span><span class="lnt"> 15
</span><span class="lnt"> 16
</span><span class="lnt"> 17
</span><span class="lnt"> 18
</span><span class="lnt"> 19
</span><span class="lnt"> 20
</span><span class="lnt"> 21
</span><span class="lnt"> 22
</span><span class="lnt"> 23
</span><span class="lnt"> 24
</span><span class="lnt"> 25
</span><span class="lnt"> 26
</span><span class="lnt"> 27
</span><span class="lnt"> 28
</span><span class="lnt"> 29
</span><span class="lnt"> 30
</span><span class="lnt"> 31
</span><span class="lnt"> 32
</span><span class="lnt"> 33
</span><span class="lnt"> 34
</span><span class="lnt"> 35
</span><span class="lnt"> 36
</span><span class="lnt"> 37
</span><span class="lnt"> 38
</span><span class="lnt"> 39
</span><span class="lnt"> 40
</span><span class="lnt"> 41
</span><span class="lnt"> 42
</span><span class="lnt"> 43
</span><span class="lnt"> 44
</span><span class="lnt"> 45
</span><span class="lnt"> 46
</span><span class="lnt"> 47
</span><span class="lnt"> 48
</span><span class="lnt"> 49
</span><span class="lnt"> 50
</span><span class="lnt"> 51
</span><span class="lnt"> 52
</span><span class="lnt"> 53
</span><span class="lnt"> 54
</span><span class="lnt"> 55
</span><span class="lnt"> 56
</span><span class="lnt"> 57
</span><span class="lnt"> 58
</span><span class="lnt"> 59
</span><span class="lnt"> 60
</span><span class="lnt"> 61
</span><span class="lnt"> 62
</span><span class="lnt"> 63
</span><span class="lnt"> 64
</span><span class="lnt"> 65
</span><span class="lnt"> 66
</span><span class="lnt"> 67
</span><span class="lnt"> 68
</span><span class="lnt"> 69
</span><span class="lnt"> 70
</span><span class="lnt"> 71
</span><span class="lnt"> 72
</span><span class="lnt"> 73
</span><span class="lnt"> 74
</span><span class="lnt"> 75
</span><span class="lnt"> 76
</span><span class="lnt"> 77
</span><span class="lnt"> 78
</span><span class="lnt"> 79
</span><span class="lnt"> 80
</span><span class="lnt"> 81
</span><span class="lnt"> 82
</span><span class="lnt"> 83
</span><span class="lnt"> 84
</span><span class="lnt"> 85
</span><span class="lnt"> 86
</span><span class="lnt"> 87
</span><span class="lnt"> 88
</span><span class="lnt"> 89
</span><span class="lnt"> 90
</span><span class="lnt"> 91
</span><span class="lnt"> 92
</span><span class="lnt"> 93
</span><span class="lnt"> 94
</span><span class="lnt"> 95
</span><span class="lnt"> 96
</span><span class="lnt"> 97
</span><span class="lnt"> 98
</span><span class="lnt"> 99
</span><span class="lnt">100
</span><span class="lnt">101
</span><span class="lnt">102
</span><span class="lnt">103
</span><span class="lnt">104
</span><span class="lnt">105
</span><span class="lnt">106
</span><span class="lnt">107
</span><span class="lnt">108
</span><span class="lnt">109
</span><span class="lnt">110
</span><span class="lnt">111
</span><span class="lnt">112
</span><span class="lnt">113
</span><span class="lnt">114
</span><span class="lnt">115
</span><span class="lnt">116
</span><span class="lnt">117
</span><span class="lnt">118
</span><span class="lnt">119
</span><span class="lnt">120
</span><span class="lnt">121
</span><span class="lnt">122
</span><span class="lnt">123
</span><span class="lnt">124
</span><span class="lnt">125
</span><span class="lnt">126
</span><span class="lnt">127
</span><span class="lnt">128
</span><span class="lnt">129
</span><span class="lnt">130
</span><span class="lnt">131
</span><span class="lnt">132
</span><span class="lnt">133
</span><span class="lnt">134
</span><span class="lnt">135
</span><span class="lnt">136
</span><span class="lnt">137
</span><span class="lnt">138
</span><span class="lnt">139
</span><span class="lnt">140
</span><span class="lnt">141
</span><span class="lnt">142
</span><span class="lnt">143
</span><span class="lnt">144
</span><span class="lnt">145
</span><span class="lnt">146
</span><span class="lnt">147
</span><span class="lnt">148
</span><span class="lnt">149
</span><span class="lnt">150
</span><span class="lnt">151
</span><span class="lnt">152
</span><span class="lnt">153
</span><span class="lnt">154
</span><span class="lnt">155
</span><span class="lnt">156
</span><span class="lnt">157
</span><span class="lnt">158
</span><span class="lnt">159
</span><span class="lnt">160
</span><span class="lnt">161
</span><span class="lnt">162
</span><span class="lnt">163
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;pthread.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;semaphore.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;stdio.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="c1">// Set either of these to 1 to prevent CPU reordering
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="cp">#define USE_CPU_FENCE              0
</span></span></span><span class="line"><span class="cl"><span class="cp">#define USE_SINGLE_HW_THREAD       0  </span><span class="c1">// Supported on Linux, but not Cygwin or PS3
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl"><span class="cp">#if USE_SINGLE_HW_THREAD
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;sched.h&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">//-------------------------------------
</span></span></span><span class="line"><span class="cl"><span class="c1">//  MersenneTwister
</span></span></span><span class="line"><span class="cl"><span class="c1">//  A thread-safe random number generator with good randomness
</span></span></span><span class="line"><span class="cl"><span class="c1">//  in a small number of instructions. We&#39;ll use it to introduce
</span></span></span><span class="line"><span class="cl"><span class="c1">//  random timing delays.
</span></span></span><span class="line"><span class="cl"><span class="c1">//-------------------------------------
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="cp">#define MT_IA  397
</span></span></span><span class="line"><span class="cl"><span class="cp">#define MT_LEN 624
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">MersenneTwister</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">m_buffer</span><span class="p">[</span><span class="n">MT_LEN</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">m_index</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">public</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">MersenneTwister</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">seed</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Declare noinline so that the function call acts as a compiler barrier:
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">unsigned</span> <span class="kt">int</span> <span class="nf">integer</span><span class="p">()</span> <span class="n">__attribute__</span><span class="p">((</span><span class="n">noinline</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">MersenneTwister</span><span class="o">::</span><span class="n">MersenneTwister</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">seed</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Initialize by filling with the seed, then iterating
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="c1">// the algorithm a bunch of times to shuffle things up.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">MT_LEN</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">m_buffer</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">=</span> <span class="n">seed</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">m_index</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o">&lt;</span> <span class="n">MT_LEN</span> <span class="o">*</span> <span class="mi">100</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="n">integer</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">MersenneTwister</span><span class="o">::</span><span class="n">integer</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Indices
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="n">m_index</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">i2</span> <span class="o">=</span> <span class="n">m_index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">i2</span> <span class="o">&gt;=</span> <span class="n">MT_LEN</span><span class="p">)</span> <span class="n">i2</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="c1">// wrap-around
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">int</span> <span class="n">j</span> <span class="o">=</span> <span class="n">m_index</span> <span class="o">+</span> <span class="n">MT_IA</span><span class="p">;</span> <span class="k">if</span> <span class="p">(</span><span class="n">j</span> <span class="o">&gt;=</span> <span class="n">MT_LEN</span><span class="p">)</span> <span class="n">j</span> <span class="o">-=</span> <span class="n">MT_LEN</span><span class="p">;</span> <span class="c1">// wrap-around
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Twist
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">s</span> <span class="o">=</span> <span class="p">(</span><span class="n">m_buffer</span><span class="p">[</span><span class="n">i</span><span class="p">]</span> <span class="o">&amp;</span> <span class="mh">0x80000000</span><span class="p">)</span> <span class="o">|</span> <span class="p">(</span><span class="n">m_buffer</span><span class="p">[</span><span class="n">i2</span><span class="p">]</span> <span class="o">&amp;</span> <span class="mh">0x7fffffff</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">r</span> <span class="o">=</span> <span class="n">m_buffer</span><span class="p">[</span><span class="n">j</span><span class="p">]</span> <span class="o">^</span> <span class="p">(</span><span class="n">s</span> <span class="o">&gt;&gt;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">^</span> <span class="p">((</span><span class="n">s</span> <span class="o">&amp;</span> <span class="mi">1</span><span class="p">)</span> <span class="o">*</span> <span class="mh">0x9908B0DF</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">m_buffer</span><span class="p">[</span><span class="n">m_index</span><span class="p">]</span> <span class="o">=</span> <span class="n">r</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">m_index</span> <span class="o">=</span> <span class="n">i2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// Swizzle
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">r</span> <span class="o">^=</span> <span class="p">(</span><span class="n">r</span> <span class="o">&gt;&gt;</span> <span class="mi">11</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">r</span> <span class="o">^=</span> <span class="p">(</span><span class="n">r</span> <span class="o">&lt;&lt;</span> <span class="mi">7</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0x9d2c5680UL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">r</span> <span class="o">^=</span> <span class="p">(</span><span class="n">r</span> <span class="o">&lt;&lt;</span> <span class="mi">15</span><span class="p">)</span> <span class="o">&amp;</span> <span class="mh">0xefc60000UL</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">r</span> <span class="o">^=</span> <span class="p">(</span><span class="n">r</span> <span class="o">&gt;&gt;</span> <span class="mi">18</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="n">r</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">//-------------------------------------
</span></span></span><span class="line"><span class="cl"><span class="c1">//  Main program, as decribed in the post
</span></span></span><span class="line"><span class="cl"><span class="c1">//-------------------------------------
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="n">sem_t</span> <span class="n">beginSema1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">sem_t</span> <span class="n">beginSema2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="n">sem_t</span> <span class="n">endSema</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="n">X</span><span class="p">,</span> <span class="n">Y</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="n">r1</span><span class="p">,</span> <span class="n">r2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span><span class="o">*</span> <span class="nf">thread1Func</span><span class="p">(</span><span class="kt">void</span><span class="o">*</span> <span class="n">param</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">MersenneTwister</span> <span class="n">random</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(;;)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">sem_wait</span><span class="p">(</span><span class="o">&amp;</span><span class="n">beginSema1</span><span class="p">);</span>  <span class="c1">// Wait for signal
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="k">while</span> <span class="p">(</span><span class="n">random</span><span class="p">.</span><span class="n">integer</span><span class="p">()</span> <span class="o">%</span> <span class="mi">8</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{}</span>  <span class="c1">// Random delay
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl">        <span class="c1">// ----- THE TRANSACTION! -----
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="n">X</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="cp">#if USE_CPU_FENCE
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="k">asm</span> <span class="k">volatile</span><span class="p">(</span><span class="s">&#34;mfence&#34;</span> <span class="o">:::</span> <span class="s">&#34;memory&#34;</span><span class="p">);</span>  <span class="c1">// Prevent CPU reordering
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="cp">#else
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="c1">//asm volatile(&#34;&#34; ::: &#34;memory&#34;);  // Prevent compiler reordering
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="n">r1</span> <span class="o">=</span> <span class="n">Y</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">sem_post</span><span class="p">(</span><span class="o">&amp;</span><span class="n">endSema</span><span class="p">);</span>  <span class="c1">// Notify transaction complete
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>  <span class="c1">// Never returns
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span><span class="o">*</span> <span class="nf">thread2Func</span><span class="p">(</span><span class="kt">void</span><span class="o">*</span> <span class="n">param</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">MersenneTwister</span> <span class="n">random</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(;;)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">sem_wait</span><span class="p">(</span><span class="o">&amp;</span><span class="n">beginSema2</span><span class="p">);</span>  <span class="c1">// Wait for signal
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="k">while</span> <span class="p">(</span><span class="n">random</span><span class="p">.</span><span class="n">integer</span><span class="p">()</span> <span class="o">%</span> <span class="mi">8</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{}</span>  <span class="c1">// Random delay
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>
</span></span><span class="line"><span class="cl">        <span class="c1">// ----- THE TRANSACTION! -----
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="n">Y</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="cp">#if USE_CPU_FENCE
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="k">asm</span> <span class="k">volatile</span><span class="p">(</span><span class="s">&#34;mfence&#34;</span> <span class="o">:::</span> <span class="s">&#34;memory&#34;</span><span class="p">);</span>  <span class="c1">// Prevent CPU reordering
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="cp">#else
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="c1">//asm volatile(&#34;&#34; ::: &#34;memory&#34;);  // Prevent compiler reordering
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>        <span class="n">r2</span> <span class="o">=</span> <span class="n">X</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">        <span class="n">sem_post</span><span class="p">(</span><span class="o">&amp;</span><span class="n">endSema</span><span class="p">);</span>  <span class="c1">// Notify transaction complete
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nb">NULL</span><span class="p">;</span>  <span class="c1">// Never returns
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Initialize the semaphores
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">sem_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">beginSema1</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">sem_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">beginSema2</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">sem_init</span><span class="p">(</span><span class="o">&amp;</span><span class="n">endSema</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// Spawn the threads
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">pthread_t</span> <span class="n">thread1</span><span class="p">,</span> <span class="n">thread2</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">pthread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">thread1</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">thread1Func</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">pthread_create</span><span class="p">(</span><span class="o">&amp;</span><span class="n">thread2</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">,</span> <span class="n">thread2Func</span><span class="p">,</span> <span class="nb">NULL</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="cp">#if USE_SINGLE_HW_THREAD
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>    <span class="c1">// Force thread affinities to the same cpu core.
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">cpu_set_t</span> <span class="n">cpus</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">CPU_ZERO</span><span class="p">(</span><span class="o">&amp;</span><span class="n">cpus</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">CPU_SET</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">cpus</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">pthread_setaffinity_np</span><span class="p">(</span><span class="n">thread1</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">cpu_set_t</span><span class="p">),</span> <span class="o">&amp;</span><span class="n">cpus</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">pthread_setaffinity_np</span><span class="p">(</span><span class="n">thread2</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">cpu_set_t</span><span class="p">),</span> <span class="o">&amp;</span><span class="n">cpus</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="cp">#endif
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl">    <span class="c1">// Repeat the experiment ad infinitum
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="kt">int</span> <span class="n">detected</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">iterations</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="p">;</span> <span class="n">iterations</span><span class="o">++</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// Reset X and Y
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="n">X</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="n">Y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// Signal both threads
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="n">sem_post</span><span class="p">(</span><span class="o">&amp;</span><span class="n">beginSema1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">sem_post</span><span class="p">(</span><span class="o">&amp;</span><span class="n">beginSema2</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// Wait for both threads
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="n">sem_wait</span><span class="p">(</span><span class="o">&amp;</span><span class="n">endSema</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="n">sem_wait</span><span class="p">(</span><span class="o">&amp;</span><span class="n">endSema</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="c1">// Check if there was a simultaneous reorder
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="k">if</span> <span class="p">(</span><span class="n">r1</span> <span class="o">==</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="n">r2</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">detected</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">printf</span><span class="p">(</span><span class="s">&#34;%d reorders detected after %d iterations</span><span class="se">\n</span><span class="s">&#34;</span><span class="p">,</span> <span class="n">detected</span><span class="p">,</span> <span class="n">iterations</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>  <span class="c1">// Never returns
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>W tym programie używamy dwóch zmiennych atomowych <code>x</code> i <code>y</code>, które są inicjowane wartością 0. Wątek <code>t1</code> zapisuje wartość 1 do <code>x</code> i <code>y</code>, podczas gdy wątek <code>t2</code> wczytuje wartości <code>y</code> i <code>x</code>. Używamy relaksowanej kolejności pamięci (<code>std::memory_order_relaxed</code>), która pozwala na reordering instrukcji.</p>
<p>Jeśli procesor przestawi kolejność instrukcji w taki sposób, że odczyt <code>y</code> zostanie wykonany przed odczytem <code>x</code>, program zlicza taką sytuację jako reordering.</p>
<p>Po wielokrotnym uruchomieniu programu liczba reorderingów może być różna. Procesor x86 ma silną kolejność pamięci, więc reordering instrukcji może być rzadko spotykany. Przetestuj ten program na różnych konfiguracjach sprzętowych, aby zobaczyć, jak efekty reorderingu instrukcji różnią się w zależności od sprzętu.</p>
<blockquote>
<p>Ref:</p>
<ul>
<li><a href="https://preshing.com/20120515/memory-reordering-caught-in-the-act/">Memory Reordering Caught in the Act</a></li>
<li><a href="https://preshing.com/20140709/the-purpose-of-memory_order_consume-in-cpp11/">The Purpose of memory_order_consume in C++11</a></li>
</ul>
</blockquote>
<h1 id="porównanie-jedno--i-wielordzeniowych-procesorów">Porównanie jedno- i wielordzeniowych procesorów:</h1>
<h2 id="różnice">Różnice</h2>
<p>Jednordzeniowe i wielordzeniowe procesory to dwa różne typy układów scalonych stosowanych w komputerach. Definicje, zalety i wady każdego z nich.</p>
<p><strong>Jednordzeniowy procesor (single-core processor)</strong></p>
<p>Definicja: Procesor jednordzeniowy to układ scalony z jednym rdzeniem CPU, który może wykonywać tylko jedną instrukcję na raz.</p>
<p>Zalety:</p>
<ul>
<li>Mniejsza złożoność układu: Jednordzeniowe procesory są mniej skomplikowane w porównaniu do wielordzeniowych, co może prowadzić do mniejszego zużycia energii i niższych kosztów produkcji.</li>
<li>Łatwiejsza implementacja: Programowanie dla jednordzeniowych procesorów jest prostsze, ponieważ nie ma konieczności zarządzania równoczesnością.</li>
</ul>
<p>Wady:</p>
<ul>
<li>Niska wydajność: W przypadku zadań wielowątkowych, jednordzeniowe procesory mają niższą wydajność niż ich wielordzeniowe odpowiedniki, ponieważ mogą wykonywać tylko jedno zadanie na raz.</li>
<li>Szybsze osiąganie limitów wydajności: Ponieważ jednordzeniowe procesory mają tylko jeden rdzeń, mogą szybciej osiągnąć swoje limity wydajności, co prowadzi do niższej wydajności w porównaniu do wielordzeniowych procesorów.</li>
</ul>
<p>Przykład w C++:</p>
<p><strong>Lab_11</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span><span class="lnt">7
</span><span class="lnt">8
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="mi">5</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span> <span class="n">c</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">c</span> <span class="o">=</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Suma: &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">c</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>Wielordzeniowy procesor (multi-core processor)</strong></p>
<p>Definicja: Wielordzeniowy procesor to układ scalony z dwoma lub więcej rdzeniami CPU, które mogą równocześnie wykonywać wiele instrukcji.</p>
<p>Zalety:</p>
<ul>
<li>Wyższa wydajność: Wielordzeniowe procesory są bardziej wydajne dla zadań wielowątkowych, ponieważ mogą równocześnie wykonywać wiele zadań.</li>
<li>Skalowalność: Wielordzeniowe procesory mogą być łatwiej skalowane, co prowadzi do wyższej wydajności w porównaniu do jednordzeniowych procesorów.</li>
<li>Energooszczędność: W przypadku zastosowań o małym obciążeniu, wielordzeniowe procesory mogą oszczędzać energię poprzez wyłączanie nieużywanych rdzeni.</li>
</ul>
<p>Wady:</p>
<ul>
<li>Wyższa złożoność układu: Wielordzeniowe procesory są bardziej skomplikowane niż jednordzeniowe, co może prowadzić do wyższego zużycia energii i wyższych kosztów produkcji.</li>
<li>Trudniejsza implementacja: Programowanie dla wielordzeniowych procesorów może być trudniejsze, ponieważ wymaga zarządzania równoczesnością i synchronizacją między wątkami.</li>
</ul>
<p>Przykład w C++:</p>
<p><strong>Lab_12</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;thread&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">add</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">c</span> <span class="o">=</span> <span class="n">a</span> <span class="o">+</span> <span class="n">b</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Suma: &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">c</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">sub</span><span class="p">(</span><span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">c</span> <span class="o">=</span> <span class="n">a</span> <span class="o">-</span> <span class="n">b</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Różnica: &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">c</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">a</span> <span class="o">=</span> <span class="mi">5</span><span class="p">,</span> <span class="n">b</span> <span class="o">=</span> <span class="mi">3</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">std</span><span class="o">::</span><span class="kr">thread</span> <span class="n">thread1</span><span class="p">(</span><span class="n">add</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="n">std</span><span class="o">::</span><span class="kr">thread</span> <span class="n">thread2</span><span class="p">(</span><span class="n">sub</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">thread1</span><span class="p">.</span><span class="n">join</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="n">thread2</span><span class="p">.</span><span class="n">join</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>W powyższym przykładzie używamy biblioteki <code>&lt;thread&gt;</code> w języku C++ do tworzenia dwóch wątków, które wykonują funkcje <code>add()</code> i <code>sub()</code> równocześnie na wielordzeniowym procesorze. Dzięki temu można równocześnie obliczyć sumę i różnicę dwóch liczb, co pokazuje zaletę wielordzeniowego procesora w porównaniu do jednordzeniowego procesora.</p>
<p>Jednordzeniowe procesory są prostsze, ale mniej wydajne, szczególnie w przypadku zadań wielowątkowych. Wielordzeniowe procesory oferują wyższą wydajność dla zadań wielowątkowych, ale wymagają bardziej zaawansowanego zarządzania równoczesnością i synchronizacją w kodzie programu. Wybór pomiędzy nimi zależy od konkretnych wymagań i ograniczeń projektu.</p>
<blockquote>
<p><strong><em>UWAGA:</em></strong> Problem wyścigu (race condition)</p>
</blockquote>
<blockquote>
<p>Ref:</p>
<ul>
<li><a href="https://brooker.co.za/blog/2014/12/06/random.html">Make Your Program Slower With Threads</a></li>
</ul>
</blockquote>
<h2 id="hyper-threading">Hyper-threading</h2>
<p>Hyper-threading to technologia opracowana przez firmę Intel, która pozwala na wykonywanie dwóch lub więcej wątków na jednym rdzeniu procesora, zwiększając wydajność procesora w zadaniach wielowątkowych. Technologia ta polega na tym, że jeden rdzeń procesora posiada dwa lub więcej zestawów rejestrów, które są niezależne dla każdego wątku. Dzięki temu rdzeń może wykonywać wiele wątków równocześnie, wykorzystując jednocześnie swoje zasoby sprzętowe.</p>
<p>W uproszczonym procesorze z technologią Hyper-threading można uwzględnić następujące elementy:</p>
<ol>
<li>
<p>Rdzeń procesora: Jednostka wykonawcza (ALU), jednostka sterująca oraz pamięć podręczna (cache). Rdzeń procesora wykonuje instrukcje z kolejnych wątków.</p>
</li>
<li>
<p>Zestawy rejestrów: Każdy wątek posiada swój własny zestaw rejestrów, takich jak licznik programu (PC) oraz rejestry ogólnego przeznaczenia. W przypadku procesora z technologią Hyper-threading, rdzeń posiada dwa lub więcej zestawów rejestrów, które są niezależne dla każdego wątku.</p>
</li>
<li>
<p>Mechanizm przemiennego wykonania instrukcji (Instruction interleaving): Procesor z technologią Hyper-threading wykonuje instrukcje z różnych wątków w sposób przemienny. Gdy jeden wątek jest zablokowany, np. na wynik operacji I/O, procesor może kontynuować wykonywanie instrukcji z innego wątku, dzięki czemu zasoby sprzętowe rdzenia są lepiej wykorzystane.</p>
</li>
<li>
<p>Mechanizm równoczesnego dekodowania (Simultaneous multithreading, SMT): Procesor z technologią Hyper-threading może równocześnie dekodować i wykonywać instrukcje z różnych wątków, co przyczynia się do zwiększenia wydajności procesora w zadaniach wielowątkowych.</p>
</li>
<li>
<p>Mechanizm zarządzania wątkami: Procesor z technologią Hyper-threading posiada mechanizm zarządzania wątkami, który kontroluje ich wykonanie, przydzielanie zasobów oraz obsługę zdarzeń, takich jak przerwania czy wyjątki.</p>
</li>
</ol>
<p>Podsumowując, technologia Hyper-threading pozwala na efektywne wykorzystanie zasobów sprzętowych rdzenia procesora, zwiększając jego wydajność w zadaniach wielowątkowych. W procesorze z technologią Hyper-threading znajduje się rdzeń, który posiada dwa lub więcej niezależnych zestawów rejestrów, umożliwiających równoczesne wykonywanie instrukcji z różnych wątków. Procesor z Hyper-threading posiada także mechanizmy takie jak Instruction interleaving, Simultaneous multithreading (SMT) oraz zarządzanie wątkami, które kontrolują wykonanie, przydzielanie zasobów oraz obsługę zdarzeń.</p>
<p>Oto kilka zalet i wad technologii Hyper-threading:</p>
<p>Zalety:</p>
<ul>
<li>Zwiększona wydajność: Technologia Hyper-threading pozwala na lepsze wykorzystanie zasobów rdzenia procesora, co prowadzi do zwiększenia wydajności w zadaniach wielowątkowych.</li>
<li>Lepsza przepustowość: Dzięki możliwości równoczesnego wykonywania instrukcji z różnych wątków, procesor z technologią Hyper-threading może osiągnąć wyższą przepustowość w porównaniu do procesora bez tej technologii.</li>
<li>Efektywność energetyczna: Procesory z technologią Hyper-threading mogą wykorzystywać swoje zasoby sprzętowe efektywniej, co może prowadzić do oszczędności energii.</li>
</ul>
<p>Wady:</p>
<ul>
<li>Zwiększona złożoność: Technologia Hyper-threading wprowadza dodatkową złożoność w architekturze procesora, co może prowadzić do wyższych kosztów produkcji i trudności w debugowaniu.</li>
<li>Potencjalne problemy z synchronizacją: W przypadku równoczesnego wykonywania wielu wątków na jednym rdzeniu, mogą wystąpić problemy z synchronizacją oraz konkurencją o zasoby sprzętowe.</li>
<li>Wydajność w zależności od rodzaju zadania: Technologia Hyper-threading przynosi korzyści głównie w zadaniach wielowątkowych, a jej wpływ na wydajność w zadaniach jednowątkowych może być ograniczony.</li>
</ul>
<p>Warto zauważyć, że technologia Hyper-threading nie jest jedyną dostępną techniką SMT (Simultaneous multithreading) - inne firmy, takie jak AMD, opracowały własne technologie SMT, takie jak SMT w procesorach AMD Ryzen, które oferują podobne możliwości wykonywania wielu wątków na jednym rdzeniu procesora. W zastosowaniach praktycznych, wybór procesora z technologią Hyper-threading czy innymi technologiami SMT zależy od potrzeb konkretnego projektu oraz rodzaju zadań, które mają być realizowane.</p>
<p>Diagram procesora z technologią Hyper-threading:</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">Procesor z technologią Hyper-threading
</span></span><span class="line"><span class="cl">1. Rdzeń procesora
</span></span><span class="line"><span class="cl">    a. Jednostka arytmetyczno-logiczna (ALU)
</span></span><span class="line"><span class="cl">    b. Rejestry
</span></span><span class="line"><span class="cl">        i. Zestaw rejestrów dla wątku 1
</span></span><span class="line"><span class="cl">        ii. Zestaw rejestrów dla wątku 2
</span></span><span class="line"><span class="cl">    c. Pamięć podręczna (cache)
</span></span><span class="line"><span class="cl">    d. Kontroler wykonania
</span></span><span class="line"><span class="cl">        i. Pobieranie instrukcji
</span></span><span class="line"><span class="cl">        ii. Dekodowanie instrukcji
</span></span><span class="line"><span class="cl">        iii. Wykonanie instrukcji
</span></span><span class="line"><span class="cl">2. Kontroler pamięci
</span></span><span class="line"><span class="cl">    a. Pamięć RAM
</span></span><span class="line"><span class="cl">3. Kontroler wejścia/wyjścia (I/O)
</span></span></code></pre></td></tr></table>
</div>
</div><p>Symulacja działania procesora z HT</p>
<p><strong>Lab_13</strong></p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span><span class="lnt">18
</span><span class="lnt">19
</span><span class="lnt">20
</span><span class="lnt">21
</span><span class="lnt">22
</span><span class="lnt">23
</span><span class="lnt">24
</span><span class="lnt">25
</span><span class="lnt">26
</span><span class="lnt">27
</span><span class="lnt">28
</span><span class="lnt">29
</span><span class="lnt">30
</span><span class="lnt">31
</span><span class="lnt">32
</span><span class="lnt">33
</span><span class="lnt">34
</span><span class="lnt">35
</span><span class="lnt">36
</span><span class="lnt">37
</span><span class="lnt">38
</span><span class="lnt">39
</span><span class="lnt">40
</span><span class="lnt">41
</span><span class="lnt">42
</span><span class="lnt">43
</span><span class="lnt">44
</span><span class="lnt">45
</span><span class="lnt">46
</span><span class="lnt">47
</span><span class="lnt">48
</span><span class="lnt">49
</span><span class="lnt">50
</span><span class="lnt">51
</span><span class="lnt">52
</span><span class="lnt">53
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-cpp" data-lang="cpp"><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;iostream&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;thread&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;vector&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp">#include</span> <span class="cpf">&lt;chrono&gt;</span><span class="cp">
</span></span></span><span class="line"><span class="cl"><span class="cp"></span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">Processor</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"><span class="k">public</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">    <span class="n">Processor</span><span class="p">()</span> <span class="o">:</span> <span class="n">registers</span><span class="p">{{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">},</span> <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="mi">0</span><span class="p">}}</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kt">void</span> <span class="nf">execute</span><span class="p">(</span><span class="kt">int</span> <span class="n">thread_id</span><span class="p">,</span> <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&amp;</span><span class="n">operation</span><span class="p">,</span> <span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="k">if</span> <span class="p">(</span><span class="n">operation</span> <span class="o">==</span> <span class="s">&#34;add&#34;</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">registers</span><span class="p">[</span><span class="n">thread_id</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">a</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="n">registers</span><span class="p">[</span><span class="n">thread_id</span><span class="p">][</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">b</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">            <span class="kt">int</span> <span class="n">result</span> <span class="o">=</span> <span class="n">add</span><span class="p">(</span><span class="n">thread_id</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">            <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Wątek &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">thread_id</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;: &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">a</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; + &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">b</span> <span class="o">&lt;&lt;</span> <span class="s">&#34; = &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">result</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;Wątek &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">thread_id</span> <span class="o">&lt;&lt;</span> <span class="s">&#34;: Nieznana operacja &#34;</span> <span class="o">&lt;&lt;</span> <span class="n">operation</span> <span class="o">&lt;&lt;</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">private</span><span class="o">:</span>
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">add</span><span class="p">(</span><span class="kt">int</span> <span class="n">thread_id</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">std</span><span class="o">::</span><span class="n">this_thread</span><span class="o">::</span><span class="n">sleep_for</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">chrono</span><span class="o">::</span><span class="n">seconds</span><span class="p">(</span><span class="mi">1</span><span class="p">));</span> <span class="c1">// Symulacja czasu wykonania operacji
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>        <span class="k">return</span> <span class="n">registers</span><span class="p">[</span><span class="n">thread_id</span><span class="p">][</span><span class="mi">0</span><span class="p">]</span> <span class="o">+</span> <span class="n">registers</span><span class="p">[</span><span class="n">thread_id</span><span class="p">][</span><span class="mi">1</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="kt">int</span> <span class="n">registers</span><span class="p">[</span><span class="mi">2</span><span class="p">][</span><span class="mi">2</span><span class="p">];</span> <span class="c1">// Rejestry dla dwóch wątków
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">void</span> <span class="nf">task</span><span class="p">(</span><span class="n">Processor</span> <span class="o">&amp;</span><span class="n">processor</span><span class="p">,</span> <span class="kt">int</span> <span class="n">thread_id</span><span class="p">,</span> <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="o">&amp;</span><span class="n">operation</span><span class="p">,</span> <span class="kt">int</span> <span class="n">a</span><span class="p">,</span> <span class="kt">int</span> <span class="n">b</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">processor</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="n">thread_id</span><span class="p">,</span> <span class="n">operation</span><span class="p">,</span> <span class="n">a</span><span class="p">,</span> <span class="n">b</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="n">Processor</span> <span class="n">processor</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="c1">// Przykład zadań do wykonania
</span></span></span><span class="line"><span class="cl"><span class="c1"></span>    <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="n">tuple</span><span class="o">&lt;</span><span class="kt">int</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="p">,</span> <span class="kt">int</span><span class="p">,</span> <span class="kt">int</span><span class="o">&gt;&gt;</span> <span class="n">tasks</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">0</span><span class="p">,</span> <span class="s">&#34;add&#34;</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="mi">5</span><span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="p">{</span><span class="mi">1</span><span class="p">,</span> <span class="s">&#34;add&#34;</span><span class="p">,</span> <span class="mi">7</span><span class="p">,</span> <span class="mi">2</span><span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o">&lt;</span><span class="n">std</span><span class="o">::</span><span class="kr">thread</span><span class="o">&gt;</span> <span class="n">threads</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="k">const</span> <span class="k">auto</span> <span class="o">&amp;</span><span class="nl">task_args</span> <span class="p">:</span> <span class="n">tasks</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="n">threads</span><span class="p">.</span><span class="n">emplace_back</span><span class="p">(</span><span class="n">task</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">ref</span><span class="p">(</span><span class="n">processor</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o">&lt;</span><span class="mi">0</span><span class="o">&gt;</span><span class="p">(</span><span class="n">task_args</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o">&lt;</span><span class="mi">1</span><span class="o">&gt;</span><span class="p">(</span><span class="n">task_args</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o">&lt;</span><span class="mi">2</span><span class="o">&gt;</span><span class="p">(</span><span class="n">task_args</span><span class="p">),</span> <span class="n">std</span><span class="o">::</span><span class="n">get</span><span class="o">&lt;</span><span class="mi">3</span><span class="o">&gt;</span><span class="p">(</span><span class="n">task_args</span><span class="p">));</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">for</span> <span class="p">(</span><span class="k">auto</span> <span class="o">&amp;</span><span class="kr">thread</span> <span class="o">:</span> <span class="n">threads</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="kr">thread</span><span class="p">.</span><span class="n">join</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></td></tr></table>
</div>
</div><p>W powyższym kodzie, klasa <code>Processor</code> symuluje prosty procesor z technologią Hyper-threading. Ma jeden rdzeń, który może wykonywać operacje dodawania. Rejestry są podzielone na dwa zestawy, po jednym dla każdego wątku. W funkcji <code>execute</code>, procesor dekoduje i wykonuje operacje na podstawie identyfikatora wątku.</p>
<p>W funkcji <code>main</code>, tworzymy dwa wątki, które wykonują operacje dodawania równocześnie. Dzięki temu symulator ilustruje, jak procesor z technologią Hyper-threading może wykonywać wiele wątków na jednym rdzeniu procesora.</p>
<h2 id="scenariusz-problemu-i-porównanie-rozwiązania-na-procesorze-jedno--i-wielordzeniowym">Scenariusz problemu i porównanie rozwiązania na procesorze jedno- i wielordzeniowym.</h2>
<!-- ## Pomysły na dodatkowe zajęcia

- Omów wyzwania związane z programowaniem wielowątkowym, takie jak synchronizacja, wyścigi (race conditions) i blokady (deadlocks)

- Studium przypadku:
	- Rzeczywisty procesor, na przykład Intel Core i7 lub AMD Ryzen - analiza jego architektury, cyklu rozkazowego i potoku rozkazowego.
	- Zadanie z optymalizacją: Sposoby optymalizacji potoku rozkazowego dla wybranego procesora, uwzględniając możliwe hazardy.
	- Przeprowadzenie eksperymentów z programami i porównanie wydajności na różnych konfiguracjach procesora (jedno- i wielordzeniowych).

- Laboratorium z mikrokontrolerów:
	- Zaprogramowanie prostego mikrokontrolera, takiego jak Arduino lub STM32, aby zrozumieć, jak działają cykl rozkazowy i potok rozkazowy w praktyce.
	- Zadanie z analizą: analiza wykonywania programu na mikrokontrolerze, uwzględniając opóźnienia wynikające z cyklu rozkazowego i potoku rozkazowego.
	- Optymalizacja programu na mikrokontrolerze, zmniejszając ilość cykli rozkazowych potrzebnych do wykonania zadania.

- Symulacja architektur procesorów:
	- Symulatory architektur procesorów, takie jak SimpleScalar, Gem5 lub QEMU.
	- Uruchomienie prostego programu na symulatorze i analiza wyników w kontekście cyklu rozkazowego i potoku rozkazowego.
	- Zadanie z eksploracją: Eksperymentowanie z różnymi konfiguracjami potoku rozkazowego, takimi jak liczba etapów, buforów czy też rozwiązania hazardów, aby zobaczyć, jak wpłyną na wydajność.

	> Ref:
	>	[Installing gem5 simulator on Windows WSL2](https://gist.github.com/rajesh-s/bd123ca1e65b95eb38220cd944670e3a)

- Analiza wydajności i skalowania:
	- Analiza wydajności programów na różnych konfiguracjach procesorów, takich jak jedno- i wielordzeniowe, a także o ocena wpływu potoku rozkazowego na wyniki.
	- Analiza skalowania programów na różnych konfiguracjach procesorów, szczególnie w przypadku programów wielowątkowych, i ocenę wpływu potoku rozkazowego na skalowanie. -->
<h1 id="komunikacja-z-pamięcią---odczyt">Komunikacja z pamięcią - odczyt</h1>
<blockquote>
<p>Ref:</p>
<ul>
<li><a href="https://akkadia.org/drepper/cpumemory.pdf">What Every Programmer Should Know About Memory</a></li>
</ul>
</blockquote>
<h2 id="rodzaje">Rodzaje</h2>
<ul>
<li>
<p>Pamięć podręczna procesora: Jest to niewielka ilość pamięci wbudowana w jednostkę centralną komputera (CPU), która przechowuje często używane dane i instrukcje. Pamięć podręczna CPU przyspiesza procesorowi dostęp do danych i instrukcji, dzięki czemu nie musi on tak często sięgać do wolniejszej pamięci głównej lub urządzeń pamięci masowej.</p>
</li>
<li>
<p>Pamięć podręczna: Jest to niewielka część pamięci głównej (RAM) odłożona jako tymczasowy obszar przechowywania często używanych danych. Buforowanie pamięci pomaga poprawić wydajność aplikacji poprzez skrócenie czasu dostępu do danych z wolniejszych nośników pamięci, takich jak dyski twarde lub sieci.</p>
</li>
<li>
<p>Pamięć podręczna dysku: Jest to część pamięci głównej (RAM) używana do przechowywania danych, które zostały niedawno odczytane lub zapisane na dysku, takim jak dysk twardy lub dysk półprzewodnikowy. Buforowanie dysku pomaga zmniejszyć liczbę operacji odczytu i zapisu na dysku, poprawiając ogólną wydajność systemu.
Pamięć podręczna przeglądarki: Jest to tymczasowy obszar przechowywania treści internetowych, takich jak strony HTML, obrazy i inne media, które są przechowywane w pamięci podręcznej przeglądarki internetowej. Gdy użytkownik odwiedza stronę internetową, jego przeglądarka przechowuje kopię zawartości strony w pamięci podręcznej. Gdy użytkownik ponownie odwiedza tę samą stronę internetową, przeglądarka może załadować zawartość z pamięci podręcznej zamiast pobierać ją ponownie, co może skrócić czas ładowania strony.</p>
</li>
<li>
<p>Rozproszona pamięć podręczna: Jest to pamięć podręczna, która jest współdzielona przez wiele komputerów w sieci i służy do przechowywania często używanych danych, które są rozproszone na wielu serwerach. Zmniejszając potrzebę dostępu do danych z wielu serwerów, rozproszone buforowanie może poprawić wydajność systemów rozproszonych. Rozproszone buforowanie może również poprawić skalowalność aplikacji, ponieważ dane mogą być buforowane w wielu lokalizacjach, co oznacza, że więcej jednoczesnych użytkowników może uzyskać dostęp do danych przy mniejszej liczbie żądań</p>
</li>
</ul>
<h2 id="czym-jest-pamięć-podręczna-w-procesorze">Czym jest pamięć podręczna (w procesorze)?</h2>
<p>Pamięć podręczna (ang. cache memory) to typ pamięci w komputerze, który przechowuje dane, do których komputer często się odwołuje. W przeciwieństwie do głównej pamięci komputera (RAM), pamięć podręczna jest zazwyczaj znacznie szybsza, ale ma też znacznie mniejszą pojemność.</p>
<p>Podstawowym celem pamięci podręcznej jest zwiększenie efektywności działania komputera. Gdy komputer potrzebuje danych, najpierw sprawdza, czy są one przechowywane w pamięci podręcznej. Jeżeli tak, dane są ładowane stamtąd, co jest szybsze niż ładowanie ich z pamięci RAM lub dysku twardego. Jeżeli danych nie ma w pamięci podręcznej, są one ładowane z innej pamięci i jednocześnie umieszczane w pamięci podręcznej, aby były dostępne na przyszłość.</p>
<p>Pamięć podręczna jest organizowana na kilka poziomów (L1, L2, L3, itd.), gdzie L1 jest najbliżej procesora (i zazwyczaj najszybsza, ale też najmniejsza), a kolejne poziomy są coraz dalej (i zazwyczaj coraz wolniejsze, ale większe).</p>
<p>Diagramy, które pokazują, jak działa pamięć podręczna, mogą być różne w zależności od szczegółów implementacji i architektury. Poniżej znajduje się proste wyjaśnienie na przykładzie trzech poziomów pamięci podręcznej (L1, L2, L3):</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt"> 1
</span><span class="lnt"> 2
</span><span class="lnt"> 3
</span><span class="lnt"> 4
</span><span class="lnt"> 5
</span><span class="lnt"> 6
</span><span class="lnt"> 7
</span><span class="lnt"> 8
</span><span class="lnt"> 9
</span><span class="lnt">10
</span><span class="lnt">11
</span><span class="lnt">12
</span><span class="lnt">13
</span><span class="lnt">14
</span><span class="lnt">15
</span><span class="lnt">16
</span><span class="lnt">17
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">  CPU
</span></span><span class="line"><span class="cl">   |
</span></span><span class="line"><span class="cl">   | (najbliżej CPU, najmniejsza, najwyższa prędkość)
</span></span><span class="line"><span class="cl">   |
</span></span><span class="line"><span class="cl">  L1 Cache
</span></span><span class="line"><span class="cl">   |
</span></span><span class="line"><span class="cl">   | (dalej od CPU, większa, trochę wolniejsza)
</span></span><span class="line"><span class="cl">   |
</span></span><span class="line"><span class="cl">  L2 Cache
</span></span><span class="line"><span class="cl">   |
</span></span><span class="line"><span class="cl">   | (jeszcze dalej od CPU, jeszcze większa, jeszcze wolniejsza)
</span></span><span class="line"><span class="cl">   |
</span></span><span class="line"><span class="cl">  L3 Cache
</span></span><span class="line"><span class="cl">   |
</span></span><span class="line"><span class="cl">   | (najdalej od CPU, największa, najwolniejsza)
</span></span><span class="line"><span class="cl">   |
</span></span><span class="line"><span class="cl">  Main Memory (RAM)
</span></span></code></pre></td></tr></table>
</div>
</div><p><em>Pentium M</em></p>
<table>
  <thead>
      <tr>
          <th>To Where</th>
          <th>Cycles</th>
      </tr>
  </thead>
  <tbody>
      <tr>
          <td>Register</td>
          <td>≤ 1</td>
      </tr>
      <tr>
          <td>L1d</td>
          <td>∼ 3</td>
      </tr>
      <tr>
          <td>L2</td>
          <td>∼ 14</td>
      </tr>
      <tr>
          <td>Main Memory</td>
          <td>∼ 240</td>
      </tr>
  </tbody>
</table>
<p>Drepper, (what every programmer should know&hellip;)</p>
<p><a href="https://colin-scott.github.io/personal_website/research/interactive_latency.html">Latency Numbers</a></p>
<h2 id="pobieranie-danych-do-pamięci-podręcznej">Pobieranie danych do pamięci podręcznej</h2>
<p>Dane są pobierane do pamięci podręcznej przez proces zwanym polityką pamięci podręcznej (ang. cache policy). Istnieją różne strategie zarządzania pamięcią podręczną, ale dwie najpopularniejsze to:</p>
<ol>
<li>
<p><strong>LRU (Least Recently Used):</strong> W tej strategii, gdy pamięć podręczna jest pełna i trzeba dodać nowe dane, usuwany jest element, który nie był używany przez najdłuższy czas. Idea jest taka, że jeśli dane nie były używane od dawna, prawdopodobnie nie będą potrzebne w najbliższej przyszłości.</p>
</li>
<li>
<p><strong>LFU (Least Frequently Used):</strong> W tej strategii, gdy pamięć podręczna jest pełna i trzeba dodać nowe dane, usuwany jest element, który był używany najrzadziej. Ta strategia zakłada, że jeśli dane były rzadko używane w przeszłości, prawdopodobnie nie będą często używane w przyszłości.</p>
</li>
</ol>
<p>Gdy komputer potrzebuje danych, najpierw sprawdza, czy są one przechowywane w pamięci podręcznej. Jeżeli tak, dane są ładowane stamtąd, co jest znacznie szybsze niż ładowanie ich z pamięci RAM lub dysku twardego. To jest nazywane &ldquo;trafieniem&rdquo; (ang. cache hit). Jeżeli danych nie ma w pamięci podręcznej, to jest nazywane &ldquo;pudłem&rdquo; (ang. cache miss) i dane są ładowane z wolniejszego źródła (np. pamięci RAM lub dysku twardego), a następnie umieszczane w pamięci podręcznej, aby były dostępne na przyszłość.</p>
<p>W przypadku pudła, dane mogą być ładowane do pamięci podręcznej na dwa główne sposoby:</p>
<ul>
<li>
<p><strong>Polityka pobierania przy pudle (ang. fetch on miss):</strong> Gdy dane nie są w pamięci podręcznej, są one pobierane z wolniejszego źródła i umieszczane w pamięci podręcznej.</p>
</li>
<li>
<p><strong>Polityka pobierania z wyprzedzeniem (ang. prefetch):</strong> W tej strategii, komputer próbuje przewidzieć, jakie dane będą potrzebne w przyszłości i ładować je do pamięci podręcznej z wyprzedzeniem, zanim będą rzeczywiście potrzebne.</p>
</li>
</ul>
<p>Oczywiście, te strategie są uproszczeniami, a rzeczywiste systemy pamięci podręcznej mogą korzystać z bardziej skomplikowanych algorytmów i strategii, które biorą pod uwagę wiele czynników, takich jak lokalność odwołań do danych (tj. tendencja do odwoływania się do tych samych danych wielokrotnie w krótkim okresie czasu) czy hierarchię pamięci podręcznej.</p>
<h2 id="nomenklatura">Nomenklatura</h2>
<p>Level 1 data cache - 48 kB, 12 way, 64 sets, 64 B line size, latency 5, per core</p>
<ol>
<li>
<p>48 kB: The size of the L1 data cache is 48 kilobytes. This is the total amount of data that can be stored in the cache. Smaller caches are faster but can store less data, while larger caches can store more data but may be slower.</p>
</li>
<li>
<p>12 way: This refers to the cache&rsquo;s associativity, which determines how cache lines can be mapped to cache sets. In a 12-way associative cache, each cache set can hold 12 different cache lines. Higher associativity can reduce the likelihood of cache conflicts (when multiple cache lines map to the same cache set), but may increase access latency.</p>
</li>
<li>
<p>64 sets: The cache is divided into 64 sets. Each set can store multiple cache lines, as determined by the cache&rsquo;s associativity (in this case, 12-way).</p>
</li>
<li>
<p>64 B line size: The size of each cache line is 64 bytes. When data is fetched from the main memory, it is brought into the cache in blocks called cache lines. A larger cache line size can improve spatial locality (the likelihood that nearby memory locations will be accessed), but may also result in more unused data being fetched.</p>
</li>
<li>
<p>Latency 5: The cache latency is 5 clock cycles. This is the time it takes for the processor to access data stored in the L1 cache.</p>
</li>
<li>
<p>Per core: This specification is for an L1 data cache that is dedicated to each core in a multicore processor. Each core has its own L1 data cache, which can help improve performance by reducing contention for cache resources between cores.</p>
</li>
</ol>
<h2 id="pamięć-wirtualna">Pamięć Wirtualna</h2>
<p>Pamięć wirtualna to technika zarządzania pamięcią, która pozwala na wykorzystanie dysku twardego jako rozszerzenia pamięci fizycznej RAM. Dzięki temu programy mogą używać więcej pamięci, niż jest dostępna fizycznie w systemie.</p>
<p>System operacyjny przypisuje każdemu programowi obszar pamięci, który nazywany jest przestrzenią adresową. Każda przestrzeń adresowa jest podzielona na bloki o stałym rozmiarze, zwane stronami. W systemach z pamięcią wirtualną, nie wszystkie strony muszą być zawsze przechowywane w pamięci RAM. Kiedy program próbuje odwołać się do strony, która nie jest obecnie w pamięci, system operacyjny przenosi ją z dysku do RAM.</p>
<p>Pamięć wirtualna ma kilka zalet.</p>
<ul>
<li>Pozwala na uruchamianie programów, które wymagają więcej pamięci, niż jest dostępne.</li>
<li>Poprawia bezpieczeństwo, ponieważ programy nie mają bezpośredniego dostępu do pamięci RAM, co utrudnia wykorzystanie błędów w programach do ataków na system.</li>
</ul>
<p>Jednak pamięć wirtualna ma też swoje wady. Przede wszystkim, jest wolniejsza od pamięci RAM, ponieważ odczyt i zapis na dysk są wolniejsze niż operacje w pamięci. Po drugie, jeśli system operacyjny musi często przenosić strony pomiędzy RAM a dyskiem (co nazywa się &ldquo;thrashing&rdquo;), może to poważnie obniżyć wydajność systemu.</p>
<p>Mechanizmy potrzebne do implementacji pamięci wirtualnej:</p>
<ol>
<li>
<p><strong>Obsługa stronicowania pamięci (paging):</strong> Procesory muszą mieć mechanizm umożliwiający mapowanie przestrzeni adresowej na strony pamięci. W rzeczywistości to stronicowanie umożliwia obsługę pamięci wirtualnej - strony, które nie są obecnie potrzebne, mogą być przeniesione na dysk twardy, a następnie ponownie załadowane do pamięci RAM, gdy są potrzebne.</p>
</li>
<li>
<p><strong>Mechanizm zarządzania pamięcią (MMU - Memory Management Unit):</strong> MMU to sprzętowy komponent procesora, który przetwarza i kontroluje wszystkie odwołania do pamięci. MMU jest odpowiedzialny za translację adresów wirtualnych na adresy fizyczne. Jest to kluczowe dla obsługi pamięci wirtualnej, ponieważ pozwala programom &ldquo;myśleć&rdquo;, że mają dostęp do ciągłego bloku pamięci, podczas gdy w rzeczywistości ich strony mogą być rozproszone w różnych miejscach pamięci fizycznej.</p>
</li>
<li>
<p><strong>Mechanizmy ochrony pamięci:</strong> Procesory muszą mieć mechanizmy umożliwiające kontrolę dostępu do pamięci. Dzięki temu system operacyjny może zapobiegać sytuacjom, w których jeden proces próbuje odczytać lub zapisywać w obszarze pamięci innego procesu.</p>
</li>
<li>
<p><strong>Mechanizmy obsługi przerwań:</strong> Kiedy program próbuje odwołać się do strony, która nie jest obecnie w pamięci, procesor generuje przerwanie (tzw. page fault), które jest obsługiwane przez system operacyjny. System operacyjny wtedy przenosi stronę z dysku do pamięci i kontynuuje wykonywanie programu.</p>
</li>
</ol>
<p>Każda z tych cech jest kluczowa dla obsługi pamięci wirtualnej i jest obecna we współczesnych procesorach.</p>
<p><strong>Lab_15</strong></p>
<p>W poniższym programie przetestujemy dwa różne sposoby dostępu do pamięci: sekwencyjny i losowy. Porównamy czas wykonania obu podejść, które mogą wpływać na wykorzystanie pamięci cache.</p>
<p>Ćwiczenie:
Proszę uruchomić program, opisać w sprawozdaniu jego wynik.</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$lab_15.exe &lt;iterations&gt; &lt;seq/random&gt;
</span></span><span class="line"><span class="cl">              &lt;50-1000&gt;    &lt;seq/random&gt;
</span></span></code></pre></td></tr></table>
</div>
</div><p>Należy modyfikować ilość iteracji: 50 75 100, uruchamiając dla dostępu sekwencyjnego i losowego.</p>
<blockquote>
<p>Ref:</p>
<ul>
<li><a href="https://lwn.net/Articles/252125/">Memory part 2: CPU caches</a></li>
</ul>
</blockquote>
<p>W symulatorze mamy prostą pamięć cache, która przechowuje wartości z pamięci. Procesor korzysta z cache podczas sekwencyjnego i losowego dostępu do pamięci. Symulator mierzy czas dostępu do pamięci oraz liczbę trafień cache dla obu podejść.</p>
<p>Uruchomienie tego symulatora pokaże, że sekwencyjny dostęp do pamięci jest szybszy niż losowy, ponieważ lepiej wykorzystuje pamięć cache. Ponadto, liczba trafień cache jest większa dla sekwencyjnego dostępu do pamięci w porównaniu z losowym dostępem.</p>
<p>Zmiana parametrów symulatora (rozmiar pamięci, rozmiar cache, liczba iteracji) w celu zrozumienia, jak wpływają na wyniki.</p>
<p>Symulator pamięci podręcznej (cache) typu direct-mapped</p>
<p><strong>Lab_17</strong></p>
<p>Proszę uruchomić program, opisać w sprawozdaniu jego wynik. Należy kilka razy zmodyfikować parametry:</p>
<ul>
<li><code>-c 1024 -b 32 -n 10000 -m 2048</code></li>
<li><code>-c 1024 -b 64 -n 10000 -m 2048</code></li>
<li><code>-c 2048 -b 32 -n 10000 -m 4096</code></li>
<li><code>-c 2048 -b 64 -n 10000 -m 4096</code></li>
<li>inna konfiguracja wg uznania z taką samą liczbą iteracji</li>
<li>inna konfiguracja wg uznania z taką samą liczbą iteracji</li>
</ul>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code><span class="lnt">1
</span><span class="lnt">2
</span><span class="lnt">3
</span><span class="lnt">4
</span><span class="lnt">5
</span><span class="lnt">6
</span></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"><span class="line"><span class="cl">$lab_17.exe -c 1024 -b 32 -n 10000 -m 1024
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  -c, --cache size
</span></span><span class="line"><span class="cl">  -b, --block size
</span></span><span class="line"><span class="cl">  -n, --iteration
</span></span><span class="line"><span class="cl">  -m, --memory size
</span></span></code></pre></td></tr></table>
</div>
</div><p><strong>Lab_18</strong> Prefetch</p>
<p>Proszę uruchomić program, opisać w sprawozdaniu jego wynik. Należy kilka razy zmodyfikować parametry:</p>
<ul>
<li><code>-c 1024 -b 32 -n 10000 -m 2048 -d 1</code></li>
<li><code>-c 1024 -b 64 -n 10000 -m 2048 -d 2</code></li>
<li><code>-c 2048 -b 32 -n 10000 -m 4096 -d 4</code></li>
<li><code>-c 2048 -b 64 -n 10000 -m 4096 -d 8</code></li>
<li>inna konfiguracja wg uznania z taką samą liczbą iteracji</li>
<li>inna konfiguracja wg uznania z taką samą liczbą iteracji</li>
</ul>
<p>$lab_18.exe -c 1024 -b 32 -n 10000 -m 1024 -d 8</p>
<p>-c, &ndash;cache size
-b, &ndash;block size
-n, &ndash;iteration
-m, &ndash;memory size
-d, &ndash;prefetch distance</p>
<div class="highlight"><div class="chroma">
<table class="lntable"><tr><td class="lntd">
<pre tabindex="0" class="chroma"><code></code></pre></td>
<td class="lntd">
<pre tabindex="0" class="chroma"><code class="language-fallback" data-lang="fallback"></code></pre></td></tr></table>
</div>
</div>]]></content:encoded></item></channel></rss>