{"id":972,"date":"2016-10-24T23:20:06","date_gmt":"2016-10-24T21:20:06","guid":{"rendered":"https:\/\/blog.mi.hdm-stuttgart.de\/?p=972"},"modified":"2023-08-06T21:53:42","modified_gmt":"2023-08-06T19:53:42","slug":"why-is-parallel-programming-so-hard-to-express","status":"publish","type":"post","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/10\/24\/why-is-parallel-programming-so-hard-to-express\/","title":{"rendered":"Why is parallel programming so hard to express?"},"content":{"rendered":"<p>by&nbsp;Johannes Frey, Hannes Buchwald, Stephan Soller, Walter Kriha, Benjamin Binder<\/p>\n<p>While trying to understand Hoares famous paper <a href=\"http:\/\/spinroot.com\/courses\/summer\/Papers\/hoare_1978.pdf\" target=\"_blank\" rel=\"noopener\">Communicating sequential processes<\/a> we stumbled upon some interesting&nbsp;problems and concepts referring to parallel programming. In this post we want to share some of the&nbsp;insights we gained by&nbsp;discussing the matter.<\/p>\n<p><!--more--><\/p>\n<h2>Parallelism is difficult<\/h2>\n<p>Humans are not really made for multitasking. We are able to do more than one task at the same time, if all the different tasks have the same goal&nbsp;and can be performed without paying much attention to them.&nbsp;An example would be driving a car.&nbsp;But it\u2019s getting harder if the tasks are similar to each other and demand the same amount of attention, like calculating different sums.<\/p>\n<p>Take for example this&nbsp;simple calculation:<\/p>\n<p style=\"text-align: center;\">(2+6) \u00d7&nbsp;(7-3)<\/p>\n<p>One&nbsp;person can only focus on calculating one of the two sums at a time. So real parallelism isn&#8217;t a natural way of thinking for us humans. Two persons however can each calculate one sum and then multiply their results. Real parallelism only works with more than one person.<\/p>\n<p>If we want to implement this&nbsp;example we could copy the principle of having two people. Each sum is calculated in a different thread. After the threads have finished we can then multiply the&nbsp;results.<\/p>\n<p>In this easy example it\u2019s not a problem to understand what is happening.&nbsp;But in a more complex scenario it\u2019s getting harder to understand who interacts with whom at what&nbsp;time.<\/p>\n<blockquote><p><a href=\"https:\/\/vimeo.com\/49718712\" target=\"_blank\" rel=\"noopener\">As a quick reminder<\/a>: Concurrency revolves around the concept of dealing with several tasks at the same time, while parallelism revolves around actually executing multiple tasks at the same time. A program build&nbsp;in a concurrent way&nbsp;can execute in parallel but doesn&#8217;t have to. It will run&nbsp;just fine sequentially&nbsp;on a&nbsp;single CPU core, too.<\/p><\/blockquote>\n<h2>Expressing&nbsp;concurrency<\/h2>\n<p>In a concurrent&nbsp;program multiple things can happen at the same time. This is easy to visualize as a few&nbsp;boxes connected by arrows:<\/p>\n<pre class=\"prettyprint lang-plain_text\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"Visualization of a parallel program\">+-----+\n| GUI |-------+-------------+\n+-----+       \u2193             \u2193\n   \u2191     +----------+ +----------+\n   |     |   read   | | download |\n   |     | metadata | | content  |\n   |     +----------+ +----------+\n   |          \u2193             |\n   |     +-----------+      |\n   +-----|  create   |\u2190-----+\n         | thumbnail |\n         +-----------+\n<\/pre>\n<p>But when written as text it&#8217;s more difficult to understand the flow of events and the dependencies between the different processes:<\/p>\n<pre class=\"prettyprint lang-plain_text\" data-start-line=\"1\" data-visibility=\"visible\" data-highlight=\"\" data-caption=\"Pseudocode of a parallel program\">gui_thread:\n    on click:\n        disk_thread.send read_file, ...\n        net_thread.send download_file, ...\n    on work_done:\n        # show result to user\n\ndisk_thread:\n    on read_file:\n        # read requested file from disk\n        compute_thread.send process_loaded_file. ...\n\nnet_thread:\n    on download_file:\n        # download requested file from server\n        compute_thread.send process_downloaded_file, ...\n\ncompute_thread:\n    on process_loaded_file and process_downloaded_file:\n        # do time consuming processing of files\n        gui_thread.send work_done, ...<\/pre>\n<p>This stems from the basic structure of text and in extension programming languages: They are structured one line <em>after<\/em>&nbsp;another, one statement <em>after<\/em> the other. Text and programming languages express things as one linear stream of things. This is a restriction of the text medium itself.<\/p>\n<p>Text as a medium is extremely useful in programming. Starting at a young age we&#8217;re trained to use language to read and write and even express our thoughts. Programming languages tap into that training and&nbsp;we can express complex thoughts in a compact way.<\/p>\n<p>But to represent the parallel structure of a program, which is basically a graph, text might not be the best choice. Maybe a simple &#8220;box and arrows&#8221; visualization better serves this purpose. There are already some examples of visual programming like <a href=\"https:\/\/docs.unrealengine.com\/latest\/INT\/Engine\/Blueprints\/\" target=\"_blank\" rel=\"noopener\">Blueprints in UE4<\/a>&nbsp;or <a href=\"http:\/\/www.ni.com\/labview\/why\/graphical-programming\/\" target=\"_blank\" rel=\"noopener\">LabVIEW<\/a>.&nbsp;This is something traditional editors and IDEs might want to pick up. Albeit in a more coarse way&nbsp;like one box per thread.<\/p>\n<p>Concepts like&nbsp;futures and event-loops are approaches to cope with&nbsp;the same problem: Mapping a graph into linear text. For some situations they work while for others they don&#8217;t. But more on that later.<\/p>\n<h2>Helping the programmer with concepts<\/h2>\n<p>The two concepts we will take a closer look at are <a href=\"https:\/\/youtu.be\/8aGhZQkoFbQ?t=11m53s\" target=\"_blank\" rel=\"noopener\">event-loops<\/a> and <a href=\"http:\/\/docs.scala-lang.org\/overviews\/core\/futures.html\" target=\"_blank\" rel=\"noopener\">futures<\/a>. They can be found in programming languages like <a href=\"http:\/\/clojure.org\/\" target=\"_blank\" rel=\"noopener\">Clojure<\/a>, or in frameworks like <a href=\"https:\/\/nodejs.org\/docs\/latest-v5.x\/api\/events.html#events_events\" target=\"_blank\" rel=\"noopener\">Node.js<\/a>. Even though both concepts share the same ground (concurrent programming), they vastly differ in their approach, their style and the&nbsp;restrictions they enforce.<\/p>\n<p>In essence both approaches allow us to break up the rather atomic chain of definition, execution and immediate result.<\/p>\n<h3>Futures<\/h3>\n<p>Futures allow us to fire up a specific task on another thread, while the main program keeps running. If, at some point in the <em>future<\/em>&nbsp;;-), we are interested in the actual value, we have to explicitly ask the future reference for its value. As long as the value is &#8220;ready&#8221; when we ask for it,&nbsp;we are good. Using futures blends perfectly with writing linear&nbsp;programming. Because you don&#8217;t have to deal with callbacks, the program stays very clean and readable.<\/p>\n<h3>Event-Loops<\/h3>\n<p>The Event-Loop approach also gives away control but with the help of callbacks. In its center is&nbsp;one single-threaded loop that runs&nbsp;&#8220;forever&#8221;. This is called the event loop.<\/p>\n<p>If an event is fired that is interesting to someone,&nbsp;a message is pushed into a queue together with a&nbsp;callback associated with the event. Whenever there is computing time left (aka the call stack is empty), messages get pulled from the queue and are&nbsp;processed. The processing of the messages is never interrupted, so&nbsp;there is no pre-emption and you can always be sure your code finished correctly.<\/p>\n<h2>Blocking and non-blocking calls<\/h2>\n<p>In the realms of CPUs, a single-core processor deals with concurrency by interleaving tasks onto the processor with the help of the scheduler. By doing so, the CPU provides each program with the illusion of exclusive processor possession, which makes multitasking possible.&nbsp;A multi-core processor however deals with concurrency by actually executing tasks on multiple cores and thereby yielding &#8220;true&#8221; parallelism.<\/p>\n<p>So why do we have to wrap our head around this low-level concept?<\/p>\n<p>Because we have&nbsp;to deal with either blocking or non-blocking operations. Ideally we want our two concepts to deal with the problem. However this doesn&#8217;t always work and we still have to keep some things in mind.<\/p>\n<h3>Futures and blocking function calls<\/h3>\n<p>When dereferencing&nbsp;a result from a future, we possibly run into a problem. As long as the value is &#8220;ready&#8221; when we ask for it, we are&nbsp;good. But if the value has to be calculated first, the dereference results in blocking the callers&nbsp;execution.<\/p>\n<h3>Event-loops and blocking function calls<\/h3>\n<p>Because programs using an event-loop are highly decoupled, the impact of using blocking function calls doesn&#8217;t seem that big from the perspective of the program.<\/p>\n<p>The event-loop however is highly depended on non-blocking function calls. Because each callback is guaranteed to <a href=\"https:\/\/developer.mozilla.org\/en\/docs\/Web\/JavaScript\/EventLoop\" target=\"_blank\" rel=\"noopener\">run until its completion<\/a>&nbsp;it can also use as much computing time as desired. This makes starvation of other callbacks a huge&nbsp;problem. If a call would take a very long time, the entire event loop would be blocked. Therefore, it is crucial that callbacks processed by an event-loop only use non-blocking function calls.<\/p>\n<h2>You have to choose<\/h2>\n<p>So essentially the main differences between these two approaches are the composition of the program and the way to retrieve the outcome of the concurrent calls.<\/p>\n<p>Futures give the programmer explicit control by allowing her\/him to spawn &#8220;independent workers&#8221; which can be logically composed in a graph-like manner.<\/p>\n<p>Event-Loops on the other hand try to invert the control by following an event-driven approach. The programmer does not explicitly request a result at given time but is forced to wait for it through asynchronous events which call back to him\/her.<\/p>\n<p>If you have to choose between one of them, maybe take a closer look at what you want to accomplish with them. If you are only using non-blocking calls, you can choose freely between both of them. If you are planning on using blocking calls however, you should stick with futures.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>by&nbsp;Johannes Frey, Hannes Buchwald, Stephan Soller, Walter Kriha, Benjamin Binder While trying to understand Hoares famous paper Communicating sequential processes we stumbled upon some interesting&nbsp;problems and concepts referring to parallel programming. In this post we want to share some of the&nbsp;insights we gained by&nbsp;discussing the matter.<\/p>\n","protected":false},"author":37,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[21,651],"tags":[49,68,25],"ppma_author":[667],"class_list":["post-972","post","type-post","status-publish","format-standard","hentry","category-system-architecture","category-system-designs","tag-architecture","tag-concurrency","tag-nodejs"],"aioseo_notices":[],"jetpack_featured_media_url":"","jetpack-related-posts":[{"id":8808,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2019\/10\/13\/how-to-build-fault-tolerant-software-systems\/","url_meta":{"origin":972,"position":0},"title":"How to build fault-tolerant software systems","author":"Raimondo Lazzara","date":"13. October 2019","format":false,"excerpt":"June 4th, 1996 - Ariane 5 rocket explodes a few seconds after being launched. The disaster was caused by a simple software error [1]. A brief introduction to the fundamental concepts of Erlang and Elixir Ever since the first electronic systems have been created, engineers and developers have strived to\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/10\/Spawn-Proc.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/10\/Spawn-Proc.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/10\/Spawn-Proc.png?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":10318,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2020\/04\/13\/open-source-batch-and-stream-processing-realtime-analysis-of-big-data\/","url_meta":{"origin":972,"position":1},"title":"Open Source Batch and Stream Processing: Realtime Analysis of Big Data","author":"Marcel Stolin","date":"13. April 2020","format":false,"excerpt":"Abstract Since the beginning of Big Data, batch processing was the most popular choice for processing large amounts of generated data. These existing processing technologies are not suitable to process the large amount of data we face today. Research works developed a variety of technologies that focus on stream processing.\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/mapreduce.jpg?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/mapreduce.jpg?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2023\/08\/mapreduce.jpg?resize=525%2C300&ssl=1 1.5x"},"classes":[]},{"id":1711,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2016\/11\/26\/snakes-exploring-pipelines-a-system-engineering-and-management-project\/","url_meta":{"origin":972,"position":2},"title":"Snakes exploring Pipelines &#8211; A \u201cSystem Engineering and Management\u201d Project","author":"Yann Loic Philippczyk","date":"26. November 2016","format":false,"excerpt":"Part 0: Introduction This series of blog entries describes a student project focused on developing an application by using methods like pair programming, test driven development and deployment pipelines. Once upon a time, which was about one and a half months ago, an illustrious group of three students found together,\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"A python. (Because snakes. Not the language.) Source: https:\/\/rashmanly.files.wordpress.com\/2008\/10\/1439659.jpg","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2016\/11\/0_1-300x300.jpg?resize=350%2C200&ssl=1","width":350,"height":200},"classes":[]},{"id":6036,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2019\/03\/10\/writing-high-performance-code-on-modern-hardware\/","url_meta":{"origin":972,"position":3},"title":"Writing High Performance Code on Modern Hardware","author":"Vincent Musch","date":"10. March 2019","format":false,"excerpt":"Today, with the use of modern hardware combined with optimized high performant code, it is an easy task to process more than 500 million images per day on a single machine. Small improvements in the underlying implementations can have extreme large impacts on the execution time and are therefore fundamentally\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/TitelBild-1.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/TitelBild-1.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/TitelBild-1.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/TitelBild-1.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/TitelBild-1.png?resize=1050%2C600&ssl=1 3x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2019\/03\/TitelBild-1.png?resize=1400%2C800&ssl=1 4x"},"classes":[]},{"id":26895,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2025\/02\/22\/parallel-sysplex-wie-ibm-z-kontinuierliche-verfugbarkeit-durch-ras-und-innovationen-des-z16-sicherstellt\/","url_meta":{"origin":972,"position":4},"title":"Parallel SysPlex: Wie IBM Z kontinuierliche Verf\u00fcgbarkeit durch RAS und Innovationen des z16 sicherstellt","author":"Luca Walz","date":"22. February 2025","format":false,"excerpt":"Note: Dieser Blogpost wurde f\u00fcr das Modul Enterprise IT (113601a) verfasst. Kurzfassung In einer zunehmend digitalisierten Welt ist hohe Verf\u00fcgbarkeit eines Systems essenziell f\u00fcr gesch\u00e4ftskritische Anwendungen. Hierbei erm\u00f6glicht eine, von IBM f\u00fcr das IBM Z-Mainframe entwickelte, Cluster Technologie eine nahezu kontinuierliche Verf\u00fcgbarkeit, welche durch dynamische Lastenverteilung, redundante Architektur und Echtzeit\u2026","rel":"","context":"In &quot;Allgemein&quot;","block_context":{"text":"Allgemein","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/allgemein\/"},"img":{"alt_text":"","src":"","width":0,"height":0},"classes":[]},{"id":1912,"url":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/2017\/02\/28\/microservices-legolizing-software-development-2\/","url_meta":{"origin":972,"position":5},"title":"Microservices &#8211; Legolizing Software Development II","author":"Korbinian Kuhn, Steffen Mauser","date":"28. February 2017","format":false,"excerpt":"Part two will take a closer look on how caching improves the heavy and frequent communication within our setup.","rel":"","context":"In &quot;System Designs&quot;","block_context":{"text":"System Designs","link":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/category\/system-designs\/"},"img":{"alt_text":"","src":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/Caching-01.png?resize=350%2C200&ssl=1","width":350,"height":200,"srcset":"https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/Caching-01.png?resize=350%2C200&ssl=1 1x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/Caching-01.png?resize=525%2C300&ssl=1 1.5x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/Caching-01.png?resize=700%2C400&ssl=1 2x, https:\/\/i0.wp.com\/blog.mi.hdm-stuttgart.de\/wp-content\/uploads\/2017\/02\/Caching-01.png?resize=1050%2C600&ssl=1 3x"},"classes":[]}],"jetpack_sharing_enabled":true,"authors":[{"term_id":667,"user_id":37,"is_guest":0,"slug":"kriha","display_name":"Walter Kriha","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/01815e5d3e065843c478e788ad48c4e8385123104ac2e0a6a77bddc916a2cd9f?s=96&d=mm&r=g","0":null,"1":"","2":"","3":"","4":"","5":"","6":"","7":"","8":""}],"_links":{"self":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/972","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/users\/37"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/comments?post=972"}],"version-history":[{"count":24,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/972\/revisions"}],"predecessor-version":[{"id":24707,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/posts\/972\/revisions\/24707"}],"wp:attachment":[{"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/media?parent=972"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/categories?post=972"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/tags?post=972"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/blog.mi.hdm-stuttgart.de\/index.php\/wp-json\/wp\/v2\/ppma_author?post=972"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}