Data Structures for Current Multi-core and Future Many-core Architectures
Structures de données pour des architectures multi-cœur actuelles et de futures architectures many-cœur
Résumé
In an era where processors are ubiquitous, programming them correctly and efficiently is an important issue. Recent trends in hardware design mark a shift towards integrating several processing cores on a single chip. Currently, a majority of those machines relies on shared, cache-coherent memory. Prototypes that integrate large amounts of cores, connected through a message-passing substrate, indicate that architectures of the near future may have these characteristics. Either of those tendencies requires that processes execute in parallel, making concurrent programming a necessary tool. The inherent difficulty of reasoning about concur- rency, however, may lead to the adverse effect of rendering the new processor architectures hard to program. In order to deal with issues such as this, we explore a threefold approach to providing ease of programmability.
The first approach employs transactional memory (TM), a promising concurrent programming paradigm. TM employs transactions in order to synchronize the access to shared data, known as data items or transactional variables. A transaction may either commit, making its updates to transactional variables visible, or abort, discarding its updates. We propose WFR- TM, an implementation that attempts to combine desirable characteristics of pessimistic and optimistic TM. In a pessimistic TM, no transaction ever aborts; however, in order to achieve that, existing TM algorithms employ locks in order to execute update transactions sequentially, decreasing the degree of achieved parallelism. Contrary to that, optimistic TM algorithms execute all transactions concurrently and commit them if they have encountered no conflict during their execution. WFR-TM provides read-only transactions that are wait-free, with the added benefit of never executing expensive synchronization operations (like CAS, LL/SC, etc). This is achieved without sacrificing the parallelism between update transactions. As such, the optimistic approach is used for the synchronization among update transactions, while they synchronize with read-only transactions pessimistically.
Transactional memory is a tool that is meant to facilitate the programmability of generic patterns of coordination among processes using a shared-memory. More specialized manners of process coordination and shared data organization may involve concurrent data structure implementations. Exemplifying that, we present a concurrent graph implementation. Graphs are versatile data structures that allow the implementation of a variety of applications, such as computer-aided design and manufacturing, video gaming, or scientific simulations. However, although data structures such as queues, stacks, and trees have been widely studied and imple- mented in the concurrent context, multi-process applications that rely on graphs still largely use a sequential implementation where accesses are synchronized through the use of global locks or partitioning, thus imposing serious performance bottlenecks. We introduce an innovative concurrent graph model that provides addition and removal of any edge of the graph, as well as atomic traversals of a part (or the entirety) of the graph. We further present Dense, a con- current graph implementation that aims at mitigating the two aforementioned implementation drawbacks. Dense achieves wait-freedom by relying on light-weight helping and provides the inbuilt capability of performing a partial snapshot on a dynamically determined subset of the
graph.
We finally aim at predicted future architecture and study general techniques for implementing distributed data structures assuming they have to run on many-core architectures that offer either partially cache-coherent memory or no cache coherence at all. In the interest of code reuse and of a common paradigm, there is recent momentum towards porting software run- time environments, originally intended for shared-memory settings, onto non-cache-coherent machines. JVM, the runtime environment of the high-productivity language Java, is a notable example. Concurrent data structure implementations are important components of the libraries that environments like these incorporate. With the goal of contributing to this effort, we present different implementations of stacks, queues, and lists.
A` une ́epoque ou` les processeurs sont omnipr ́esents, les programmer correctement et efficace- ment est un enjeu important. Les tendances r ́ecentes dans la conception de mat ́eriel montrent une ́evolution vers l’int ́egration de plusieurs cœurs de traitement sur une seule puce. Actuelle- ment, la majorit ́e de ces machines sont fond ́ees sur une m ́emoire partag ́ee avec coh ́erence de caches. Des prototypes int ́egrant de grandes quantit ́es de cœurs, reli ́es par une infrastructure de transmission de messages, indiquent que, dans un proche avenir, les architectures de pro- cesseurs vont probablement avoir ces caract ́eristiques. Ces deux tendances – m ́emoire partag ́e ou transmission de messages – exigent que les processus s’ex ́ecutent en parall`ele et rendent la programmation concurrente n ́ecessaire. Cependant, la difficult ́e inh ́erente du raisonnement sur la concurrence peut avoir un effet n ́egatif: celui de rendre ces nouvelles architectures de pro- cesseurs difficiles `a programmer. Afin de r ́esoudre ce type de probl`emes, nous explorons trois approches ayant pour but de faciliter la programmation.
Notre premi`ere approche est fond ́e sur la m ́emoire transactionnelle (TM), un paradigme de programmation concurrente tr`es prometteur. Une TM utilise des transactions afin de synchro- niser l’acc`es aux donn ́ees partag ́ees, appel ́ees aussi variables transactionnelles. Une transaction peut soit terminer (commit), rendant visibles ses modifications des variables transactionnelles, soit ́echouer (abort), annulant toutes ses modifications. Nous proposons WFR-TM, un algorithme qui tente de combiner des caract ́eristiques d ́esirables des TM optimistes et pessimistes. Dans une TM pessimiste, aucune transaction n’ ́echoue jamais; n ́eanmoins pour cela les algorithmes exis- tants utilisent des verrous pour ex ́ecuter de mani`ere s ́equentielle les transactions qui contiennent des op ́erations d’ ́ecriture. Cela diminue le degr ́e de parall ́elisme qui peut ˆetre atteint. Contraire- ment `a cela, les algorithmes TM optimistes ex ́ecutent toutes les transactions en parall`ele et les terminent si elles n’ont pas rencontr ́e de conflit au cours de leur ex ́ecution. WFR-TM fournit des transactions en lecture seule qui sont wait-free, avec l’avantage suppl ́ementaire de ne jamais ex ́ecuter d’op ́erations de synchronisation couˆteuse (comme par exemple, CAS, LL/SC, etc). Ce r ́esultat est obtenu sans sacrifier le parall ́elisme entre les transactions d’ ́ecriture. L’approche op- timiste est utilis ́e pour la synchronisation entre les transactions d’ ́ecriture, alors que l’approche pessimiste est utilis ́e pour synchroniser les transactions d’ ́ecriture avec les transactions de lec- ture.
La m ́emoire transactionnelle est un outil facilitant la programmation de mod`eles g ́en ́eriques de coordination entre des processus qui utilisent une m ́emoire partag ́ee. Les structures de donn ́ees concurrentes sont une fa ̧con plus sp ́ecialis ́ee de faire la mˆeme chose. Dans ce travail, nous pr ́esentons ́egalement une impl ́ementation concurrente de graphe. Les graphes sont des structures de donn ́ees polyvalentes qui permettent la mise en œuvre d’une vari ́et ́e d’applications, comme par exemple les simulations scientifiques ou les jeux vid ́eo. Cependant, bien que des structures de donn ́ees tel que des files, des piles, et des arbres aient ́et ́e largement ́etudi ́es et adapt ́ees en versions concurrentes, des applications multi-processus qui utilisent des graphes utilisent encore largement des versions s ́equentielles ou` les acc`es aux donn ́ees partag ́ees sont synchronis ́es par l’utilisation de verrous, ce qui entraine des pertes de performance. Nous
introduisons un nouveau mod`ele de graphes concurrents, permettant l’ajout ou la suppression de n’importe quel arc du graphe, ainsi que la travers ́ee atomique d’une partie (ou de l’int ́egralit ́e) du graphe. Nous pr ́esentons ́egalement Dense, une impl ́ementation concurrente de graphes visant `a att ́enuer les deux inconv ́enients d’impl ́ementation susmentionn ́es. Dense offre la possibilit ́e d’effectuer un snapshot partiel d’un sous-ensemble du graphe d ́efini dynamiquement.
Enfin, nous ciblons les futures architectures et ́etudions des techniques g ́en ́erales pour impl ́ementer des structures de donn ́ees distribu ́ees en supposant qu’elles vont ˆetre utilis ́ees sur des architectures many-core, qui n’offrent qu’une coh ́erence partielle de caches, voir pas de coh ́erence du tout. Dans l’int ́erˆet de la r ́eutilisation du code et afin d’offrir un paradigme com- mun, il existe depuis quelques temps une tentative d’adaptation des environnements d’ex ́ecution de logiciel, initialement pr ́evus pour m ́emoire partag ́ee, `a des machines sans coh ́erence de caches. Un exemple notable est la JVM, l’environnement d’ex ́ecution de Java. Les implementations de structure de donn ́ees distribu ́ees sont des composantes importantes des biblioth`eques incor- por ́ees dans ces environnements. Afin de contribuer `a cet effort, nous pr ́esentons diff ́erentes impl ́ementations de piles, de files et de listes.
Loading...