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

<channel>
	<title>.Net &#8211; Nearshore Software Development Company &#8211; IT Outsourcing Services</title>
	<atom:link href="https://nearshore-it.eu/pl/tag/net-pl/feed/" rel="self" type="application/rss+xml" />
	<link>https://nearshore-it.eu/pl/</link>
	<description>We are Nearshore Software Development Company with 14years of experience in delivering a large scale IT projects in the areas of PHP, JAVA, .NET, BI and MDM.</description>
	<lastBuildDate>Thu, 07 Nov 2024 14:28:05 +0000</lastBuildDate>
	<language>pl-PL</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>

<image>
	<url>https://nearshore-it.eu/wp-content/uploads/2023/01/cropped-inetum-favicon-300x300-1-32x32.png</url>
	<title>.Net &#8211; Nearshore Software Development Company &#8211; IT Outsourcing Services</title>
	<link>https://nearshore-it.eu/pl/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Kim jest .NET developer? </title>
		<link>https://nearshore-it.eu/pl/artykuly/dot-net-developer/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/dot-net-developer/#respond</comments>
		
		<dc:creator><![CDATA[Bartosz Brandt]]></dc:creator>
		<pubDate>Thu, 22 Jun 2023 11:56:10 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Organizacja]]></category>
		<category><![CDATA[.Net]]></category>
		<category><![CDATA[Kariera w IT]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/dot-net-developer/</guid>

					<description><![CDATA[.NET Developer to osoba zajmująca się przede wszystkim analizą, tworzeniem oraz rozwijaniem aplikacji, korzystając ze stacku technologicznego firmy Microsoft. Przeczytaj artykuł i dowiedz się więcej na temat roli .NET developera, jego zadań i narzędzi.]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title"></p>
    <ol>
                    <li><a href="">1.  Platforma .NET</a></li>
                    <li><a href="#Zadania-.NET-developera">2.  Zadania .NET developera</a></li>
                    <li><a href="#Rola-.NET-developera">3.  Rola .NET developera</a></li>
                    <li><a href="#Z-kim-wspołpracuje-.NET-developer">4.  Z kim współpracuje .NET developer? </a></li>
                    <li><a href="#Jak-zostac-.NET-developerem">5.  Jak zostać .NET developerem?</a></li>
                    <li><a href="#Sciezka-kariery">6.  Ścieżka kariery</a></li>
                    <li><a href="#Podsumowanie  ">7.  Podsumowanie </a></li>
            </ol>
</div>


<p><strong>Data publikacji:</strong> 4.03.2021<br><strong>Ostatnia aktualizacja:</strong> 22.06.2023</p>



<h2 class="wp-block-heading" id="Platforma-.NET">Platforma .NET&nbsp;</h2>



<p>Platforma .NET jest bardzo szeroka i od swojego początku, który miał miejsce w 2002 roku, przeszła wiele modyfikacji. </p>



<p>Platforma oferuje wiele możliwości, między innymi:&nbsp;</p>



<ul class="wp-block-list">
<li>języki programowania obiektowego, np. C# i Visual Basic;&nbsp;</li>



<li>języki programowania funkcyjnego, np. F#;&nbsp;</li>



<li>aplikacje sieci Web – ASP.NET;&nbsp;</li>



<li>aplikacje w chmurze na platformie Azure, np. Websites, WebJobs, Cloud Services;&nbsp;</li>



<li>platforma uniwersalna systemu Windows UWP, pozwalająca na tworzenie aplikacji na wiele różnych urządzeń;&nbsp;</li>



<li>aplikacje klasyczne, oparte przede wszystkim na formularzach WinForms oraz WPF;&nbsp;</li>



<li>rozwiązania mobilne na różnorodne platformy – Xamarin;&nbsp;</li>



<li>.NET Core – modułowe oprogramowanie typu „open source” dla różnych platform.&nbsp;</li>
</ul>



<h2 class="wp-block-heading" id="Zadania-.NET-developera">Zadania .NET developera &nbsp;</h2>



<p>Osoby pracujące jako .NET developerzy, poza samym programowaniem na wyżej opisanej platformie, mogą zmagać się też z innymi zadaniami, np.:&nbsp;</p>



<ul class="wp-block-list">
<li>pisaniem skryptów PowerShell, &nbsp;</li>



<li>tworzeniem automatycznych przepływów Microsoft Flow,&nbsp;</li>



<li>budowaniem aplikacji przy użyciu PowerApps, &nbsp;</li>



<li>programowaniem w innych językach, np. JavaScript, Python, Scala, C++ itp.&nbsp;</li>
</ul>



<h2 class="wp-block-heading" id="Rola-.NET-developera">Rola .NET developera&nbsp;</h2>



<p>Rola developera zależy od projektu, w którym uczestniczy, oraz od jego stanowiska i poziomu umiejętności – junior, mid, senior. W zależności od potrzeb developer musi dostosować się do stawianych wymagań. &nbsp;</p>



<p>Na początku startującego projektu jest to głównie <strong>analiza oczekiwań </strong>klienta, przygotowywanie architektury aplikacji, pisanie dokumentacji oraz tworzenie PoC, czyli Proof of Concept. Ma to na celu sprawdzenie, czy spełnienie danego wymagania jest możliwe i czy aplikacja będzie odpowiadała potrzebom klienta.&nbsp;</p>



<h2 class="wp-block-heading" id="Z-kim-wspołpracuje-.NET-developer">Z kim współpracuje .NET developer? &nbsp;</h2>



<p>.NET developer pracuje w zespole, którego członkami zazwyczaj są osoby wyspecjalizowane w różnych dziedzinach. Mogą to być:&nbsp;</p>



<ul class="wp-block-list">
<li>QA (<a href="https://nearshore-it.eu/pl/artykuly/quality-assurance-czyli-jak-zagwarantowac-jakosc-i-bezpieczenstwo-w-projektach-it/" data-type="post" data-id="3171">Quality Assurance</a>) – osoby odpowiedzialne za analizę jakości wytwarzanego oprogramowania,&nbsp;</li>



<li><a href="https://nearshore-it.eu/pl/artykuly/kim-jest-architekt-systemow-it/" data-type="post" data-id="9003">Architekci</a>, przygotowujący główne koncepcje aplikacji,&nbsp;</li>



<li>PO (<a href="https://nearshore-it.eu/pl/artykuly/product-owner-bohater-ostatniej-akcji/" data-type="post" data-id="3234">Product Owner</a>) – osoba odpowiedzialna za zbieranie wymagań klienta dotyczących budowanej aplikacji,&nbsp;</li>



<li>UI/UX designer – osoba odpowiedzialna za tworzenie konceptów graficznych,&nbsp;</li>



<li><a href="https://nearshore-it.eu/pl/artykuly/rola-scrum-mastera-w-procesie-wytwarzania-oprogramowania/" data-type="post" data-id="3185">Scrum Master</a> w zespołach prowadzonych w metodyce <a href="https://nearshore-it.eu/pl/artykuly/dlaczego-agile-bywa-niezrozumiany/" data-type="post" data-id="3225">Agile</a>.&nbsp;</li>
</ul>



<p><strong>Przeczytaj artykuł</strong>: <a href="https://nearshore-it.eu/pl/artykuly/scrum-vs-kanban/" data-type="link" data-id="https://nearshore-it.eu/pl/artykuly/scrum-vs-kanban/">Scrum vs Kanban w rozwoju oprogramowania</a></p>



<h2 class="wp-block-heading" id="Jak-zostac-.NET-developerem">Jak zostać .NET developerem? &nbsp;</h2>



<p>Aby zostać dobrym programistą, <strong>nie trzeba kończyć dedykowanych studiów – najważniejsze są chęci i motywacja do pracy.</strong> Zawód programisty wymaga ciągłego poszerzania wiedzy. W świecie IT codziennie powstają nowe frameworki, biblioteki, języki programowania. Chcąc odnaleźć się w tych warunkach, warto starać się podążać za nowymi trendami. &nbsp;</p>



<p>Oczywiście, kierunki studiów takie jak <strong>informatyka, automatyka, mechatronika czy matematyka</strong> pomogą nauczyć się podstaw programowania, jednak to od ciebie zależy, czy będziesz robić coś poza zakresem omawianym na studiach i poszerzać wiedzę na własną rękę.&nbsp;</p>



<p>Niestety często materiał wykładany na zajęciach jest przestarzały, ogólnikowy i bez dodatkowego działania z twojej strony może nie być wystarczający, by pozwolić ci dostać się na staż do dobrej firmy.&nbsp;</p>



<h2 class="wp-block-heading">A może staż w Inetum? &nbsp;</h2>



<p>Ciekawą opcją na poszerzanie wiedzy są różnego rodzaju szkolenia, kursy online czy wydarzenia organizowane przez firmy IT, np. Akademia Inetum.</p>



<p>Nasza firma daje spore możliwości rozwoju osobom o każdym stopniu zaawansowania. Osoby bez doświadczenia, będące jeszcze studentami, zazwyczaj zaczynają swoją karierę zawodową jako praktykanci lub stażyści. &nbsp;</p>



<p>Pod okiem bardziej doświadczonych pracowników zagłębiają się w świat IT, uczą programowania oraz pracy zespołowej. Następnym krokiem w karierze jest stanowisko młodszego programisty, które proponujemy osobom z bardzo dobrą oceną stażu. Jeśli developer wykazuje się samodzielnością w wykonywaniu powierzanych zadań, może przejść na stanowisko programisty regulara.&nbsp;</p>



<h2 class="wp-block-heading" id="Sciezka-kariery">Ścieżka kariery&nbsp;</h2>



<p>Kolejne kroki w ścieżce kariery zależą głównie od tego, w czym dana osoba czuje się najlepiej, w którym kierunku chce podążać. Zazwyczaj jest to stanowisko starszego programisty, który swoją wiedzą może dzielić się z młodszymi stażem kolegami, być podporą zespołu.&nbsp;</p>



<p>Równolegle można ukierunkowywać się na konsultanta, czyli osobę, która większy nacisk kładzie na kontakt z klientem, lub jako architekt, czyli decydować, w jaki sposób zaprojektować daną aplikację. Poza tym warto rozwijać <a href="https://nearshore-it.eu/pl/artykuly/jak-zbudowac-zgrany-zespol-umiejetnosci-miekkie-i-typy-osobowosci-a-praca-w-scrumie/" data-type="post" data-id="3170">kompetencje miękkie</a>, by móc zostać Team Leaderem i prowadzić swój zespołów developerów. </p>



<h2 class="wp-block-heading" id=".NET-Team-Leader">.NET Team Leader&nbsp;</h2>



<p>Będąc Team Leaderem jednego z poznańskich zespołów .NET, swoją pracę mogę podzielić na dwie główne ścieżki:&nbsp;</p>



<ul class="wp-block-list">
<li><strong>Praca jako Developer/Tech Lead </strong>w projekcie wykonywanym dla klienta. Myślę, że tutaj największymi wyzwaniami są kontakty z klientem, zbieranie wymagań oraz dostosowywanie się do ciągłych zmian zakresu prac, na których skupia się zespół. Zmiany te często są dynamiczne i wcześniej nieplanowane, czego skutkiem bywa porzucenie aktualnie opracowywanego rozwiązania.&nbsp;</li>



<li><strong>Praca jako Team Leader. </strong>W tej roli wyzwaniem jest m.in. konieczność sprawiedliwej oceny członków zespołu oraz udzielanie feedbacku na temat wykonywanej pracy – zarówno tego pozytywnego, jak i negatywnego.&nbsp;<br>&nbsp;</li>
</ul>



<h2 class="wp-block-heading" id="Podsumowanie">Podsumowanie &nbsp;</h2>



<p>Moim zdaniem plusem pracy jako developer jest możliwość ciągłego poszerzania swojej wiedzy, co w tej branży ma bardzo duże znaczenie. Tak jak pisałem wyżej, każdego dnia powstają nowe biblioteki, nowe technologie, z którymi jako dobrzy programiści powinniśmy być na bieżąco. Przez wiele osób może być to odbierane jako wada, ponieważ nie jest to praca mechaniczna, o której można zapomnieć, zamykając pokrywę laptopa. Lecz jeśli programowanie jest twoja pasją, poświęcenie dodatkowego czasu na naukę nie powinno stanowić dużego problemu!&nbsp;</p>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/dot-net-developer/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Pułapki współbieżności. Narzut synchronizacji wątków</title>
		<link>https://nearshore-it.eu/pl/artykuly/pulapki-wspolbieznosci-narzut-synchronizacji-watkow/</link>
					<comments>https://nearshore-it.eu/pl/artykuly/pulapki-wspolbieznosci-narzut-synchronizacji-watkow/#respond</comments>
		
		<dc:creator><![CDATA[Lucjan Łyczak]]></dc:creator>
		<pubDate>Wed, 29 Apr 2020 04:19:36 +0000</pubDate>
				<category><![CDATA[Artykuły]]></category>
		<category><![CDATA[Technologie]]></category>
		<category><![CDATA[.Net]]></category>
		<guid isPermaLink="false">https://nearshore-it.eu/artykuly/pulapki-wspolbieznosci-narzut-synchronizacji-watkow/</guid>

					<description><![CDATA[W powszechnym mniemaniu programowanie współbieżne zapewnia przyspieszenie działania każdej aplikacji. Entuzjaści nowinek technologicznych, którzy nie wgłębiają się w szczegóły techniczne wprowadzanych innowacji, chętnie pokuszą się też o wykorzystanie biblioteki TPL w swoim kodzie. Ci, którzy zmierzą wyniki swoich „optymalizacji”, ze zdziwieniem zauważą, że nie zawsze i nie każde użycie takich rozwiązań skutkuje przyspieszeniem działania kodu, a w wielu przypadkach może spowodować wręcz jego spowolnienie. Skąd wynika taka sytuacja?]]></description>
										<content:encoded><![CDATA[
<div class="table-of-contents">
    <p class="title">Przejdź do:</p>
    <ol>
                    <li><a href="#Punkt-wyjscia">1.  Punkt wyjścia</a></li>
                    <li><a href="#Pulapka-naiwnej-optymalizacji">2.  Pułapka naiwnej optymalizacji</a></li>
                    <li><a href="#Meandry-rownoleglosci">3.  Meandry równoległości</a></li>
                    <li><a href="#Kiedy-zrownoleglac-obliczenia">4.  Kiedy zrównoleglać obliczenia?</a></li>
                    <li><a href="#Podsumowanie-warto-robic-pomiary">5.  Podsumowanie: warto robić pomiary</a></li>
            </ol>
</div>


<h2 class="wp-block-heading" id="Punkt-wyjscia">Punkt wyjścia</h2>



<p>Programowanie współbieżne jest tematem bardzo rozległym i zawiera w sobie wiele elementów, o których trzeba pamiętać, aby dostosować sposób jego użycia do potrzeb danego scenariusza i by jego użycie nie przyniosło rezultatów odwrotnych do zamierzonych. Już sama historia ewolucji API .NETa (mechanizmy takie, jak instrukcja lock, semafory, interfejs IAsyncResult, zdarzenia, biblioteka TPL aż po klasę ValueTask) pokazuje, że temat ten nie jest łatwy nawet dla inżynierów Microsoftu. <strong>Świadomość niskopoziomowych mechanizmów działających pod tą technologią ułatwia prawidłowe zastosowanie tych narzędzi.</strong> W tym artykule zostanie poruszony tylko niewielki wycinek tego obszaru wiedzy.</p>



<p>Aby zobrazować pewne aspekty użycia programowania współbieżnego, wziąłem za przykład scenariusz, w którym chcę wyliczyć liczby pierwsze w zadanym zakresie liczb naturalnych. Aby sprawdzić, czy dana liczba jest liczbą pierwszą, posłużyłem się przykładowym kodem <a href="https://stackoverflow.com/a/15743238/4439713" target="_blank" rel="noopener">znalezionym na StackOverflow</a>:</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_grafika_2020.29.04_1.png" alt="Współbieżność w aplikacji" class="wp-image-27414" title="Pułapki współbieżności. Narzut synchronizacji wątków 1"></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Rozpocząłem od przetwarzania sekwencyjnego, by sprawdzić, ile czasu zajmuje wyliczenie liczb pierwszych w zakresie od 1 do 100. Aby zmierzyć ten czas, wykorzystałem <strong>bibliotekę BenchmarkDotNet.</strong></p>



<p>W tym celu:</p>



<ol class="wp-block-list">
<li>Stworzyłem program konsolowy (w moim przypadku wykorzystam <strong>.NET Core 3.0</strong>),</li>



<li>Dodałem paczkę nuget <strong>BenchmarkDotNet</strong> (w moim przypadku jest to wersja 0.11.5),</li>



<li>Dodałem klasę <strong>BenchmarkTest</strong></li>



<li>Do klasy <strong>BenchmarkTest</strong> dodałem wylistowaną wyżej metodę IsPrime,</li>



<li>Do klasy <strong>BenchmarkTest</strong> dodałem metodę wyliczania sekwencyjnego liczb pierwszych oraz opatrzyłem tę metodę atrybutem <strong>[Benchmark]</strong> z przestrzeni nazw <strong>BenchmarkDotNet.Attributes:</strong></li>
</ol>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_grafika_2020.29.04_2.png" alt=" class=" class="wp-image-27415" title="Pułapki współbieżności. Narzut synchronizacji wątków 2"></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Program musiał być zbudowany w trybie <strong>RELEASE</strong>, aby dać wymierne wyniki. Aby więc uniknąć usunięcia powyższej metody podczas procesu optymalizacji, powinienem był zadbać, aby jej typ zwracany nie był deklarowany jako void. Dlatego zdecydowałem, by zwracała wyliczony wynik jako listę liczb pierwszych.</p>



<ol start="6" class="wp-block-list">
<li>Do metody statycznej <strong>Program.Main</strong> dodałem wywołanie mechanizmu mierzenia wydajności testowanej metody:</li>
</ol>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_grafika_2020.29.04_3.png" alt=" class=" class="wp-image-27416" title="Pułapki współbieżności. Narzut synchronizacji wątków 3"></figure>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<ol start="7" class="wp-block-list">
<li>Zmieniłem konfigurację projektu na <strong>Release.</strong></li>
</ol>



<p>W dalszym kroku mogłem już uruchomić projekt, ale – uwaga! – aby zmniejszyć wpływ innych procesów na wyniki testu (np. trybu debuggowania z Visual Studio), zrobiłem to z linii poleceń.</p>



<p>W wyniku uruchomienia zostały wykonane wielokrotne testy, a na końcu otrzymałem tabelkę z takimi wynikami:</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_grafika_2020.29.04_4.png" alt="Tabela - wpółbieżność" class="wp-image-27417" title="Pułapki współbieżności. Narzut synchronizacji wątków 4"></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading" id="Pulapka-naiwnej-optymalizacji">Pułapka naiwnej optymalizacji</h2>



<p>Następnie chciałem zmierzyć czas potrzebny na wygenerowanie tej samej listy liczb pierwszych w sposób równoległy. W tym celu do klasy <strong>BenchmarkTest</strong> dodałem odpowiednio zmodyfikowaną metodę. Zamiast klasy <strong>Enumerable</strong> wykorzystałem ParallelEnumerable, którego metoda Range generuje równoległą sekwencję liczb (ang. parallel sequence of integral numbers):</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_grafika_2020.29.04_5.png" alt="Współbieżność w aplikacji" class="wp-image-27418" title="Pułapki współbieżności. Narzut synchronizacji wątków 5"></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Po uruchomieniu programu narzędzie BenchmarkDotNet zmierzyło średni czas wykonania dla każdej z obu metod.</p>



<p>Wyniki były następujące:</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_grafika_2020.29.04_6.png" alt="Współbieżność w aplikacji" class="wp-image-27419" title="Pułapki współbieżności. Narzut synchronizacji wątków 6"></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Jak widać, <strong>zrównoleglone zadanie zostało wykonane w czasie ok. 8 razy dłuższym</strong> niż zadanie wykonane sekwencyjnie. Skąd to może wynikać?</p>



<h2 class="wp-block-heading" id="Meandry-rownoleglosci">Meandry równoległości</h2>



<p>Microsoft na stronie <a href="https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/understanding-speedup-in-plinq" target="_blank" rel="noopener">Understanding Speedup in PLINQ</a> wyjaśnia, że jedną z przyczyn niepowodzenia optymalizacji przez zrównoleglenie jest zjawisko występowania pewnego narzutu czasu (ang. overhead) potrzebnego do synchronizacji zadań pomiędzy wątkami.</p>



<p>To zjawisko można zaobserwować, analizując zapis zdarzeń systemowych, które w systemie Windows funkcjonują pod nazwą <strong>Event Tracing for Windows.</strong> Aby zebrać i przeanalizować te zdarzenia, użyłem narzędzia <a href="https://marketplace.visualstudio.com/items?itemName=Diagnostics.ConcurrencyVisualizer2017" target="_blank" rel="noopener">Concurrency Visualizer for Visual Studio 2017</a>, które jest dodatkiem do Visual Studio 2017 (w momencie pisania tego artykułu nie istniał dodatek dla Visual Studio 2019).</p>



<p>Aby ułatwić analizę zdarzeń generowanych przez Concurrency Visualizer, chwilowo zrezygnowałem z uruchamiania analizowanego kodu przez BenchmarkDotNet, a w zamian uruchomiłem tylko raz jedną z testowanych metod – najpierw wersję sekwencyjną, potem wielowątkową. W tym celu zmodyfikowałem metodę Program.Main do poniższej postaci:</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_grafika_2020.29.04_7.png" alt="Współbieżność w aplikacji" class="wp-image-27420" title="Pułapki współbieżności. Narzut synchronizacji wątków 7"></figure>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p><span class="TextRun SCXW17250991 BCX0" data-contrast="auto"><span class="NormalTextRun SCXW17250991 BCX0" data-wac-het="1">Dodatkowo, aby pozwolić narzędziu na odczytanie dany</span></span><span class="TextRun SCXW17250991 BCX0" data-contrast="auto"><span class="NormalTextRun SCXW17250991 BCX0" data-wac-het="1">ch diagnostycznych z uruchamianego procesu,&nbsp;</span></span><span class="TextRun SCXW17250991 BCX0" data-contrast="auto"><span class="NormalTextRun SCXW17250991 BCX0" data-wac-het="1">zmodyfikowałem</span></span><span class="TextRun SCXW17250991 BCX0" data-contrast="auto"><span class="NormalTextRun SCXW17250991 BCX0" data-wac-het="1">&nbsp;plik&nbsp;</span></span><span class="TextRun SCXW17250991 BCX0" data-contrast="auto"><span class="SpellingError SCXW17250991 BCX0" data-wac-het="1">csproj</span></span><span class="TextRun SCXW17250991 BCX0" data-contrast="auto"><span class="NormalTextRun SCXW17250991 BCX0" data-wac-het="1">&nbsp;projektu, dodając&nbsp;</span></span><span class="TextRun SCXW17250991 BCX0" data-contrast="auto"><span class="NormalTextRun SCXW17250991 BCX0" data-wac-het="1">w nim&nbsp;</span></span><span class="TextRun SCXW17250991 BCX0" data-contrast="auto"><span class="NormalTextRun SCXW17250991 BCX0" data-wac-het="1">do&nbsp;</span></span><span class="TextRun SCXW17250991 BCX0" data-contrast="auto"><span class="NormalTextRun SCXW17250991 BCX0" data-wac-het="1">elementów</span></span><span class="TextRun SCXW17250991 BCX0" data-contrast="auto"><span class="NormalTextRun SCXW17250991 BCX0" data-wac-het="1">&nbsp;</span></span><span class="TextRun SCXW17250991 BCX0" data-contrast="auto"><span class="SpellingError SCXW17250991 BCX0" data-wac-het="1">PropertyGroup</span></span><span class="TextRun SCXW17250991 BCX0" data-contrast="auto"><span class="NormalTextRun SCXW17250991 BCX0" data-wac-het="1">&nbsp;poniższy fragment XML:</span></span><span class="EOP SCXW17250991 BCX0" data-ccp-props="{&quot;201341983&quot;:0,&quot;335559739&quot;:160,&quot;335559740&quot;:259}" data-wac-het="1">&nbsp;</span></p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_grafika_2020.29.04_8.png" alt="Współbieżność w aplikacji" class="wp-image-27421" title="Pułapki współbieżności. Narzut synchronizacji wątków 8"></figure>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Po przebudowaniu aplikacji uruchomiłem Visual Studio 2017 i z menu Analyze / Concurrency Visualizer wybrałem komendę <strong>Launch New Process</strong>. W okienku z parametrami wskazałem ścieżkę do pliku exe mojej aplikacji:</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter size-full"><img fetchpriority="high" decoding="async" width="1200" height="167" src="https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b1.jpg" alt="Pułapki współbieżności" class="wp-image-32494" title="Pułapki współbieżności. Narzut synchronizacji wątków 9" srcset="https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b1.jpg 1200w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b1-300x42.jpg 300w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b1-768x107.jpg 768w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b1-495x69.jpg 495w" sizes="(max-width: 1200px) 100vw, 1200px" /></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Po kliknięciu przycisku <strong>Start</strong> został uruchomiony mój program, a następnie zostały wczytane dane dotyczące zdarzeń zarejestrowanych podczas jego uruchomienia.</p>



<p>Przed przeprowadzeniem tego procesu istotne jest, aby zamykać wszystkie zbędne aplikacje, by ich działanie nie wpłynęło na wynik analizy. Dodatkowo warto tę analizę powtórzyć kilka razy, aby sprawdzić, czy wyniki są do siebie wystarczająco zbliżone, i w ten sposób upewnić się co do rzetelności wyników. Ja na potrzeby tego artykułu każdą analizę wykonałem po trzy razy i – porównując wyniki między sobą – uznałem tę liczbę powtórzeń za wystarczającą.</p>



<p>Po zakończeniu ładowania zobaczyłem taki wykres:</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="1200" height="497" src="https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b2.jpg" alt="Pułapki współbieżności" class="wp-image-32506" title="Pułapki współbieżności. Narzut synchronizacji wątków 10" srcset="https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b2.jpg 1200w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b2-300x124.jpg 300w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b2-768x318.jpg 768w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b2-495x205.jpg 495w" sizes="(max-width: 1200px) 100vw, 1200px" /></figure>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Przedstawia on stopień wykorzystania rdzeni logicznych przez uruchomioną aplikację (kolor zielony) w czasie (oś pozioma) analizy. Za pomocą kolorów szarych przedstawiony jest stopień wykorzystania rdzeni logicznych przez pozostałe procesy. Kolor biały przedstawia niewykorzystane zasoby procesora.</p>



<p>Z punktu widzenia tej analizy istotniejsze dane kryją się jednak pod elementem <strong>„Threads”</strong>. Po jego kliknięciu ukazał się taki widok:</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img decoding="async" width="1200" height="497" src="https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b3.jpg" alt="Pułapki współbieżności" class="wp-image-32503" title="Pułapki współbieżności. Narzut synchronizacji wątków 11" srcset="https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b3.jpg 1200w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b3-300x124.jpg 300w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b3-768x318.jpg 768w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b3-495x205.jpg 495w" sizes="(max-width: 1200px) 100vw, 1200px" /></figure>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>W tym widoku u góry znajduje się pasek, który znamy już z widoku <strong>„Utilization”,</strong> a który tutaj pełni funkcję osi czasu. Za pomocą czerwonej ramki ograniczonej po bokach uchwytami (czerwonymi kwadratami) zaznaczony jest obszar, dla którego w dolnej części przedstawiono dane. Przesuwając uchwyty, można ograniczyć ten zakres do określonego odcinka czasu i tym samym zobaczyć bardziej szczegółowe dane.</p>



<p>Poniżej paska osi czasu znajduje się wykres obrazujący stan wątków procesu (reprezentowanych na osi pionowej) w kolejnych momentach działania procesu (oś pozioma). W dolnej części widoku znajduje się legenda przedstawiająca znaczenie użytych kolorów, np. zielonym oznaczono stan działania (executing) wątku, a czerwonym stan synchronizacji. Na legendzie widnieją też określone w procentach udziały tych stanów w zaznaczonym obrębie czasu.</p>



<p>W przypadku uruchomienia eksperymentalnej metody, można zauważyć, że proces działa w więcej, niż 1 wątku, oraz że 58% czasu zostało poświęcone na synchronizację wątków, czyli operację kopiowania danych z obszarów pamięci zarezerwowanych dla poszczególnych wątków.<strong> Po zakończeniu pracy poszczególnych roboczych wątków następuje zebranie wyników (ewentualne dodatkowe operacje na tych wynikach). Proces ten nazywamy synchronizacją wątków.</strong> Następuje ona po zakończeniu pracy wszystkich wątków, aby zapewnić, że operacje wykonane w jednym wątku nie wpłyną w sposób niekontrolowany na dane przydzielone do innych wątków.</p>



<p>Pomimo że zastosowany sposób wyliczania liczb pierwszych był sekwencyjny, proces posiadał wiele wątków. Jest to cecha każdego procesu uruchamianego w systemie Windows – po załadowaniu aplikacji (co na wykresie jest widoczne w postaci fioletowego paska w lewej części wykresu, oznaczonego w legendzie jako proces I/O) tworzonych jest kilka wątków roboczych. Więcej informacji na ten temat można znaleźć w książce „Windows Internals. Seventh Edition. Part 1” (Pavel Yosifovich et al.) oraz – odnośnie platformy .NET – w rozdziale <em>Threads</em> dokumentacji <a href="https://github.com/dotnet/coreclr/blob/master/Documentation/botr/threading.md#special-threads" target="_blank" rel="noopener">The Book of the Runtime</a>.</p>



<p>W kolejnym kroku uruchomiłem analizę dla wersji równoległej. Zmieniłem więc odpowiednio metodę Main:</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_grafika_2020.29.04_9.png" alt="Współbieżność w aplikacji" class="wp-image-27422" title="Pułapki współbieżności. Narzut synchronizacji wątków 12"></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>i ponownie uruchomiłem <strong>narzędzie Concurrency Visualizer.</strong> Po przełączeniu się na zakładkę Threads mój wykres wyglądał w ten sposób:</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1200" height="497" src="https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b4.jpg" alt="Pułapki współbieżności" class="wp-image-32500" title="Pułapki współbieżności. Narzut synchronizacji wątków 13" srcset="https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b4.jpg 1200w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b4-300x124.jpg 300w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b4-768x318.jpg 768w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b4-495x205.jpg 495w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Z wykresu wynika, że w tym przypadku <strong>synchronizacja wątków zajęła 63% czasu</strong>.</p>



<p>Różnica pomiędzy 58% a 63% nie wydaje się być wielka, ale – jak widać po wykresie z przypadku działania sekwencyjnego – synchronizacja odbywa się nie tylko wtedy, gdy wykonywane są obliczenia wielowątkowe, ale synchronizacja jest jednym z podstawowych działań, które odbywają się w procesach. Poza tym powyższe udziały są obliczone względem czasu trwania całego procesu, który obejmuje też czas związany z ładowaniem i uruchamianiem aplikacji, zanim aplikacja rozpocznie uruchamianie kodu, który zaimplementowaliśmy (dokona obliczeń czasu liczb pierwszych). Narzędzie BenchmarkDotNet uwzględnia te czynniki podczas mierzenia wydajności.</p>



<p>Działanie i synchronizację wątków utworzonych przez <strong>Parallel.Range()</strong> można zaobserwować na podstawie zakresu działania oznaczonego ciemnofioletowym paskiem oznaczonym napisem <strong>„ParallelQueryBegin”.</strong> Aby zaobserwować działania przeprowadzane na poszczególnych wątkach i synchronizację pomiędzy nimi, na osi czasu (na wykresie na samej górze okna) zawęziłem zakres wyznaczony przez ten pasek do zakresu oznaczonego ciemnofioletowym paskiem. Na ekranie zobaczyłem wtedy taki widok:</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" width="1200" height="497" src="https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b5.jpg" alt="Pułapki współbieżności" class="wp-image-32497" title="Pułapki współbieżności. Narzut synchronizacji wątków 14" srcset="https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b5.jpg 1200w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b5-300x124.jpg 300w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b5-768x318.jpg 768w, https://nearshore-it.eu/wp-content/uploads/2020/04/jpro_grafika_2020.29.04_b5-495x205.jpg 495w" sizes="auto, (max-width: 1200px) 100vw, 1200px" /></figure>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<h2 class="wp-block-heading" id="Kiedy-zrownoleglac-obliczenia">Kiedy zrównoleglać obliczenia?</h2>



<p>Kiedy w takim razie warto zrównoleglać obliczenia? We wspomnianym artykule <a href="https://docs.microsoft.com/en-us/dotnet/standard/parallel-programming/understanding-speedup-in-plinq" target="_blank" rel="noopener">Understanding Speedup in PLINQ</a> Microsoft wyjaśnia, że musi być spełniony warunek: <strong>koszt operacji obliczeniowych powinien przewyższać narzut czasu związany z synchronizacją wątków związany z tymi obliczeniami.</strong></p>



<p>Obliczanie liczby pierwszej, według wykorzystanego w tym przykładzie algorytmu, będzie przebiegało szybciej dla małych liczb niż dla liczb większych. Na kolejnym etapie testów wróciłem do przeprowadzania benchmarków i sprawdzania średniego czasu wykonywania obliczeń dla zakresów: od 1 do 100, od 1 do 10’000 i od 1 do 1’000’000.</p>



<p>BenchmarkDotNet <a href="https://benchmarkdotnet.org/articles/features/parameterization.html" target="_blank" rel="noopener">wspomaga parametryzację</a> przeprowadzanych testów za pomocą atrybutu <strong>ParamsAttribute</strong> z przestrzeni nazw <strong>BenchmarkDotNet.Attributes.</strong> Ustawia się go na publicznej właściwości z publicznym setterem, a opatrzonej nim właściwości używa się w testowanej metodzie:</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>


<div class="wp-block-image">
<figure class="aligncenter"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_grafika_2020.29.04_10.png" alt="Współbieżność w aplikacji" class="wp-image-27423" title="Pułapki współbieżności. Narzut synchronizacji wątków 15"></figure></div>


<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Po uruchomieniu testów do tabeli wyników została dodana kolumna z wartością wykorzystanego parametru:</p>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<figure class="wp-block-image"><img decoding="async" src="https://nearshore-it.eu/wp-content/uploads/2024/09/jpro_grafika_2020.29.04_11.png" alt="Współbieżność w aplikacji" class="wp-image-27424" title="Pułapki współbieżności. Narzut synchronizacji wątków 16"></figure>



<div style="height:34px" aria-hidden="true" class="wp-block-spacer"></div>



<p>Jak widać na wynikach: im większy zakres pętli, tym bardziej korzystne okazuje się rozwiązanie wielowątkowe.</p>



<h2 class="wp-block-heading" id="Podsumowanie-warto-robic-pomiary">Podsumowanie: warto robić pomiary</h2>



<p>Temat wprowadzania współbieżności do aplikacji nie jest tematem trywialnym. W zrozumieniu tematu pomaga nie tylko znajomość dokumentacji, ale też mechanizmów systemowych działających na niskim poziomie – systemu lub nawet pamięci i procesora. Dlatego, aby upewnić się, że wprowadzenie wielowątkowości do aplikacji łączy się z realną korzyścią, warto przeprowadzać testy wydajności.</p>



<p><strong>Przeczytaj także: <a href="https://nearshore-it.eu/pl/artykuly/test-driven-development-na-co-dzien">Test-Driven Development na co dzień</a></strong></p>



<p></p>
]]></content:encoded>
					
					<wfw:commentRss>https://nearshore-it.eu/pl/artykuly/pulapki-wspolbieznosci-narzut-synchronizacji-watkow/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
