perfbook

以下は、perfbook の訳です。正確には、2014年6月時点の、Is Parallel Programming Hard, And, If So, What Can You Do About It? 著者 Paul E. McKenney 他、の kanda.motohiro@gmail.com による適当な部分の抄訳です。First Print Edition を使い、私の見つけた誤りを直しています。基本的に誤りは作者に連絡します。git リポジトリはどんどん変わっていっているようですが、前記誤り以外の変更はこの訳には取り入れません。原文と同じ、Creative Commons Attribution-Share Alike 3.0 United States license で公開します。本当は、Tex ソースに訳を埋めて製版しないといけないのですが、まあ、とりあえず、テキストだけ置きます。イラストやコードは原文を見て下さい。

これは、最初は、https://sites.google.com/site/kandamotohiro/perfbook で公開しましたが、2020 年に、ここに移動しました。classic site からここへの移行の結果、レイアウトがくずれた部分があります。ご容赦ください。

This is a Japanese translation of random portions of Is Parallel Programming Hard, And, If So, What Can You Do About It? Original English version was written by Paul E. McKenney et. al and the translation is made by kanda.motohiro@gmail.com. The first printed edition as of June 2014 is used. This translation is distributed in Creative Commons Attribution-Share Alike 3.0 United States license, same as the original one.

This contents was first published at https://sites.google.com/site/kandamotohiro/perfbook and moved here in 2020.

Is Parallel Programming Hard, And, If So, What Can You Do About It?

First Print Edition

Edited by:

Paul E. McKenney Linux Technology Center IBM Beaverton

paulmck@linux.vnet.ibm.com

April 3, 2014

Legal Statement

This work represents the views of the editor and the authors and does not necessarily represent the view of their respective employers.

Trademarks:

• IBM, zSeries, and PowerPC are trademarks or registered trademarks of Interna- tional Business Machines Corporation in the United States, other countries, or both.

• Linux is a registered trademark of Linus Torvalds.

• i386 is a trademark of Intel Corporation or its subsidiaries in the United States, other countries, or both.

• Other company, product, and service names may be trademarks or service marks of such companies.

The non-source-code text and images in this document are provided under the terms of the Creative Commons Attribution-Share Alike 3.0 United States license(*1). In brief, you may use the contents of this document for any purpose, personal, commercial, or otherwise, so long as attribution to the authors is maintained. Likewise, the document may be modified, and derivative works and translations made available, so long as such modifications and derivations are offered to the public on equal terms as the non-source-code text and images in the original document.

Source code is covered by various versions of the GPL(*2). Some of this code is GPLv2-only, as it derives from the Linux kernel, while other code is GPLv2-or-later. See the comment headers of the individual source files within the CodeSamples directory in the git archive(*3) for the exact licenses. If you are unsure of the license for a given code fragment, you should assume GPLv2-only.

Combined work © 2005-2014 by Paul E. McKenney.

(*1) http://creativecommons.org/licenses/by-sa/3.0/us/

(*2) http://www.gnu.org/licenses/gpl-2.0.html

(*3) git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/perfbook.git


Contents

1 How To Use This Book

2 Introduction

3 Hardware and its Habits

4 Tools of the Trade

5 Counting

6 Partitioning and Synchronization Design

7 Locking

8 Data Ownership

9 Deferred Processing

10 Data Structures

11 Validation

12 Formal Verification

13 Putting It All Together

14 Advanced Synchronization

15 Ease of Use

16 Conflicting Visions of the Future

A Important Questions

B Synchronization Primitives

C Why Memory Barriers?

D Read-Copy Update Implementations

F Answers to Quick Quizzes

Parallel Real-Time Computing -- This chapter is from January 31, 2015 edition

Formal Verification, 12.3 Axiomatic Approaches -- These sections are from v2017.11.22a edition.


目次

1章 この本の使い方 全訳です。

2章 前書き

3章 ハードウエアとそのくせ

4章 仕事のツール

5章 カウンティング

6章 分割と同期の設計

7章 ロック

8章 データ所有

9章 遅延処理

10章 データ構造

11章 検証

12章 形式的検証

13章 全部まとめると

14章 進んだ同期

15章 使いやすさ

16章 未来のビジョンはいろいろある

付録A 重要な質問

付録B 同期プリミティブ

付録C なぜメモリバリア?

付録D リードコピーアップデートの実装

付録F クイッククイズの答え

おまけ

並列リアルタイムコンピューティング -- これは、2015年1月31日版の15章です。

形式的検証、公理論的アプローチ -- これは、2017年11月版で増えた節です。


1章 この本の使い方

この本の目的は、あなたが、正気をなくす危険をおかさないで、共用メモリ並列マシンでのプログラムができるように助けることです。

脚注。

あるいはより正確には、並列でないプログラミングがあなたの正気に及ぼす危険に比べてそれほど多くはない程度に、でしょうか。まあ、いずれにしてもそれほどのことはありませんよ。

この本の設計方針によれば、あなたが少なくても並列プログラミングの落とし穴のいくつかを避ける手助けができるのではないかと思います。つまり、あなたはこの本を、完成した伽藍でなくて、その上にものを立てる基礎であると思うのがよいでしょう。あなたの使命、もし受け入れるならですが、は、並列プログラミングという、わくわくする分野においてさらなる進歩をすることです。その進歩は、そのうちに、この本を古臭いものとしてしまうでしょう。並列プログラミングは、誰かが言うほど難しいものではありません。この本が、あなたの並列プログラミングプロジェクトをより簡単に、より楽しいものとすることができればと思います。

つまり、かつては並列プログラミングは科学、研究、そしてグランドチャレンジプロジェクトで注目されましたが、今や速やかに1つの技術分野となってきています。なので、この本では、特定の並列プログラミング作業を調べて、それにどうアプローチするかを説明します。いくつかの驚くほど一般的なケースでは、それは自動化することもできます。

この本は、成功した並列プログラミングプロジェクトの元となった技術規範を公開することで、新しい世代の並列ハッカーを、のろのろで苦痛に満ちた車輪の再発明の必要性から解放し、その代わりに自分のエネルギーと創造性を新しいフロンティアに注力できるようにできないかという願いを込めて書かれました。並列プログラミングがあなたに、少なくても私達が得たと同じくらいの多くの楽しみ、興奮そして挑戦をもたらすことを心から祈ります!

1.1 ロードマップ

この本は、広く適用可能で何度も使われてきた設計技術のハンドブックです。ごく狭い領域にしか適用できない最適なアルゴリズムのコレクションではありません。あなたは今、1章を読んでいます。まあ、それはご存知と思います。2章は、並列プログラミングの高いレベルからの概要を示します。

3章は、共用メモリ並列ハードウエアを紹介します。結局、元になるハードウエアを理解しないで、良い並列コードを書くのは難しいです。ハードウエアは常に進化しますから、この章は常に時代遅れです。それでも、できる限り、追っかけましょう。4章は、一般的な共用メモリ並列プログラミングプリミティブのとても簡単な概要を説明します。

5章は、想像できる限り最も単純な問題の一つ、つまり、カウンティングを並列化することについて、深く考えます。ほとんど誰でも、カウンティングが何かはよくわかっているでしょうから、この章は、より典型的な計算機科学の問題を考えるのとは違って、多くの重要な並列プログラミングの問題に集中できるでしょう。私の考えでは、この章は、並列プログラミングの授業で最も多く使われていると思います。

6章は、5章で明らかになった問題を解決するための設計レベルの方法をいくつか紹介します。可能ならば並列性に、設計レベルで対処するのが重要だとわかるでしょう。Dijkstra の言葉 [Dij68] を借りれば、「後付けの並列性は、最適とはとてもいえない」です [McK12c] 。

次の3つの章は、同期についての3つの重要なアプローチを調べます。7章はロック、これは、2014年時点では、本番品質の並列プログラミングの働き馬であるとともに、並列プログラミングの最悪の悪役としても広く知られています。8章は、データ所有の概要を示します。見逃されることが多いですが、とても応用範囲の広い、強力なアプローチです。最後に、9章はいくつかの遅延処理機構を紹介します。それには、参照カウンティング、ハザードポインタ、シーケンスロック、そして RCU が含まれます。

10章は、以前の章の成果をハッシュテーブルに適用します。ハッシュテーブルは、分割可能性、それは(普通は)優れた性能とスケーラビリティにつながります、に優れるために、多く使われています。

多くの人々が涙とともに学んだように、検証なしの並列プログラミングは、確実にみじめな失敗に通じています。11章はいろいろなテストの形式を示します。もちろん、あなたのプログラムがこわれた後で信頼性をテストするのは不可能なので、12章は形式的検証の実用的アプローチのいくつかを簡単に紹介して終わります。

13章は中間の大きさの並列プログラミングの問題をいくつか集めました。これらの問題の難しさはいろいろですが、これまでの章の内容をマスターした人には調度良いと思います。

14章は、メモリバリアと、ノンブロッキング同期を含む、より進んだ同期方法を考えます。15章は、使いやすさに関して補足します。最後に、16章は可能な将来の方向性のいくつかを考えます。共用メモリ並列システム設計、ソフトウェアとハードウエアトランザクショナルメモリ、そして、並列性のための関数プログラミングを含みます。

この章の後には、付録がいくつかあります。付録C の、メモリバリアの話が、最も有名でしょう。付録F は、悪名高いクイッククイズの答えです。次の節で紹介します。

1.2 クイッククイズ

「クイッククイズ」はこの本のいたるところにあらわれます。回答は、589ページから始まる付録F にあります。いくつかは、そのクイッククイズがあるところの記述に基づいています。あなたが、その節を越えて考えないといけないものもあります。時には、現在の知識の領域を越えて考えないといけないものもあります。努力というものはいつもそうであるように、あなたがこの本から得るものは、あなたがそれにどれだけつぎ込んだかによってほぼ決まります。なので、答えを見る前に、まじめにクイッククイズを解こうと努力する読者は、並列プログラミングの理解が大いに進むということで報いられるはずです。

クイッククイズ1.1:

クイッククイズの答えはどこにありますか?

クイッククイズ1.2:

クイッククイズの問題のいくつかは、著者の観点からでなく、読者の観点からのもののように見えます。これは意図されたことですか?

クイッククイズ1.3:

このクイッククイズはどうも私の趣味に合わないみたいです。どうしたらいいですか?

つまり、あなたがそれぞれの題材に深い理解を得たいならば、あなたはクイッククイズに答えるためにそれなりの時間を使うべきです。悪く思わないでくださいね。受動的に本を読むのはとても大切なことです。しかし、本物の問題解決能力を得るには、問題を解く訓練がとても必要とされます。

私はこれを、人生遅くなってからの博士課程の課題をやっていて思い知りました。私が勉強していたのはなじみのある題材だったのですが、私は章の演習問題の中で、それほど考えずに解けるものがいかに少ないかに驚かされたものです。

脚注。

なので、私の担当教授が、私がそのクラスを放棄するのを許さなかったのは、良いことだったと思います。

自分自身を問題に答えるように強いることで、私は自分がその題材をずっと長く覚えていられるようになりました。なので、これらのクイッククイズでもって、私は、自分ではやってないことをあなたにやるようにお願いしているわけではないのです!

1.3 この本の代わりとなるもの

Knuth が学んだように、本を有限にしたいなら、焦点を合わせる必要があります。この本は、共用メモリ並列プログラミングに焦点を合わせます。ソフトウエアスタックの底に近いところにいるソフトウェアに重点を置きます。それは、オペレーティングシステムカーネル、並列データ管理システム、低レベルのライブラリ、などです。この本で使うプログラム言語は C です。 あなたがもし並列性の他の面に興味があるなら、他の本を読まれるのがよいでしょう。幸運にも、選択肢はたくさんあります。 1 並列プログラミングのもっと学術的で厳格な扱いがお好きなら、 Herlihy と Shavit の教科書 [HS08] が気にいるでしょう。この本は、ハードウエアの高いレベルの抽象化のもとでの低いレベルのプリミティブという面白い組み合わせで始まります。そして、その調子で、ロックが議論され、リスト、キュー、ハッシュテーブル、カウンタを含む単純なデータ構造が続き、最後にトランザクショナルメモリの議論があります。Michael Scott の教科書 [Sco13] は、同じ題材を、よりソフトウェアエンジニアリングに焦点を当ててアプローチします。また、これは私の知る限り最初の、正式に出版された学術教科書で、RCU だけを扱う節を持つものです。

2 もしあなたが、プログラミング言語プラグマティック観点から、並列プログラミングを学術的に取り扱ったものをお好みなら、Scott の、プログラミング言語プラグマティックの教科書 [Sco06] の、並列同時実行の章に興味を持たれるでしょう。

3 もしあなたが、オブジェクト指向パターン主義者風の並列プログラミングの扱いで、C++ に焦点を当てたものに興味があるなら、Schmidt の POSA シリーズ [SSRB00, BHS07] の2巻と4巻がおすすめです。特に、4巻は、この成果を倉庫アプリケーションに適用した面白い章がいくつかあります。この例の現実主義は、「大きな泥の玉を分割する」と題された節で特に明らかになります。そこでは、並列性に固有の問題は、多くの場合、実世界のアプリケーションを考えることに固有な問題に比べて後回しにされることがわかります。

4 もしあなたが、Linux カーネルデバイスドライバの作業をしたいなら、Corbet, Rubini、そして Kroah-Hartman の “Linux Device Drivers” [CRKH05] は欠かせません。それに、Linux Weekly News ウエブサイト (http://lwn.net/) です。Linux カーネル内部のより一般的な話題については、多くの本とリソースがあります。

5 もしあなたの主な焦点が、科学と技術計算であり、あなたがパターン主義者アプローチを好むなら、Mattson 他の教科書 [MSM05] がおすすめです。それは、Java, C/C++, OpenMP と MPI をカバーします。そのパターンは、最初は設計に、次に実装に、素晴らしくフォーカスしています。

6 もしあなたの主な焦点が、科学と技術計算であり、あなたが GPU, CUDA, と MPI に興味があるなら、Norm Matloff の “Programming on Parallel Machines” [Mat13] がおすすめです。

7 POSIX スレッドが知りたいなら、David R. Butenhof の本 [But97] がおすすめです。

8 C++11 が知りたいなら、Anthony Williams の “C++ Concurrency in Action: Practical Multithreading” [Wil12] がおすすめです。

9 C++ 、ただし、Windows 環境に興味があるなら、Dr. Dobbs Journal の、Herb Sutter’s “Effective Concurrency” シリーズ [Sut08] がおすすめです。このシリーズは、並列性に対して常識的アプローチを説明するという良い仕事をしています。

10 インテルの Threading Building Blocks を試してみたいなら、James Reinders の本 [Rei07] が、お探しのものです。

11 マルチプロセッサハードウエアキャッシュのいろいろな型の構成が、カーネル内部の実装に及ぼす影響に興味があるなら、Curt Schimmel のこの問題の古典的な扱い [Sch94] を読むべきです。

12 最後に、Java を使う人は、Doug Lea の教科書 [Lea97, GPB+07] が役に立つでしょう。

しかし、あなたが低レベルソフトウェア、特に C で書かれたソフトウェア、の並列設計の原理に興味があるなら、読み続けましょう! 1.4 サンプルソースコード この本では、ソースコードの説明をたくさんします。多くの場合、そのソースコードはこの本の git ツリーの CodeSamples ディレクトリにあります。例えば、UNIX システムなら、以下をたたけばよいです。

find CodeSamples -name rcu_rcpls.c -print

このコマンドは、9.3.5節で使う rcu_rcpls.c ファイルを位置づけます。その他のタイプのシステムにも、ファイルをファイル名で探す方法があります。

1.5 この本は誰のですか?

表紙にあるように、編集者は Paul E. McKenney という人です。しかし、編集者は貢献をありがたく受け付けます。貢献は、どのような形でもかまいません。一般的なアプローチとしては、テキスト電子メール、本の LATEX ソースへのパッチ、なんなら git pull 要求でもよいです。あなたが使いやすいものを選んで下さい。

後の2つの形式で貢献をする場合、あなたはこの本のLATEX ソースが必要でしょう。それは、git://git.kernel.org/pub/scm/linux/kernel/git/paulmck/perfbook.git にある git アーカイブにあります。git 自身は、ほとんどのメインストリーム Linux ディストリビューションの一部として使用可能です。この本の現在のLATEX ソースツリーを作成、表示するには、図1.1に示した Linux コマンドを使います。環境によっては、perfbook.pdf を表示する evince コマンドを、例えば、acroread に変える必要があるかもしれません。git clone コマンドは、あなたが最初に PDF を作るときだけ必要です。以降は、図1.2に示したコマンドを実行して、変更を取り込んで、変更済みの PDF を生成することができます。図1.2のコマンドは、図1.1のコマンドによって作成された perfbook ディレクトリで実行する必要があります。 この本のPDFは、http://kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.html と、 http://www.rdrop.com/users/paulmck/perfbook/ に、気まぐれにポストされることがあります。 パッチを貢献したり、git pull 要求を送る実際のやり方は、Linux ソースツリーの Documentation/SubmittingPatches ファイルに書いてある、Linux カーネルのやり方に似ています。一つの重要な要件は、それぞれのパッチ(あるいは git pull 要求の時はコミット)は有効な Signed-off-by: 行を含まなくてはいけないことです。それは以下のような形式です。 Signed-off-by: My Name <myname@example.org> Signed-off-by: 行を含むパッチの例として、 http://lkml.org/lkml/2007/1/15/219 を参照下さい。 Signed-off-by: 行はとても固有な意味を持つことに注意するのは重要です。つまり、あなたは以下を証明します。 1 この貢献は全部あるいは部分的に私によって作成され、私はそれをファイルが示すオープンソースライセンスの元で提供する権利を持ちます。あるいは、 2 この貢献は以前の作品を元としており、それは、私の知る限り、適切なオープンソースライセンスによってカバーされます。そして私はそのライセンスの元でその作品を修正を含めて提供する権利を持ちます。その作品は、全部あるいは部分的に私によって作成され、ファイルが示すのと同じオープンソースライセンス(私が異なるライセンスの元で提供するのを許されていない限り)の元で提供されます。あるいは、 3 この貢献は、(a), (b) あるいは (c)

訳注。1,2あるいは3の誤りでしょう。

を証明した誰か他の人が私に直接提供したものであり、私はそれを変更していません。 4 この貢献は、誰か他の人の知的所有権の主張あるいは権利から自由です。 5 私は、このプロジェクトと貢献は公的なものであり、貢献の記録(私が貢献と共に提供する、私のサインオフを含む全ての私の個人情報)は無期限に維持され、このプロジェクトあるいは関連するオープンソースライセンスに矛盾しない形で再配布される可能性があることを、理解し、合意します。 これは、Linux カーネルで使われる、Developer’s Certificate of Origin (DCO) 1.1 に似ています。#4だけが、追加されています。この追加された項目は、あなたが自分で貢献を書いたのであって、(例えば、)どこかからコピーしたのでは無いことを示します。複数の人が貢献の著者であるなら、それぞれが、Signed-off-by: 行を持たなくてはいけません。 あなたは本名を使わなくてはいけません。私は、残念ですがペンネームや匿名の貢献を受け入れることはできません。

この本の言語はアメリカ英語ですが、この本のオープンソース性は、翻訳を許します。そして私は個人的にそうしてほしいです。この本をカバーするオープンソースライセンスは、さらに、あなたが望むなら、ご自分の翻訳を売ることも許します。そのときは、私にその翻訳を一冊、(可能ならハードコピー)送ってくれるようお願いします。しかし、これは専門家としての礼儀としてお願いしているのであって、けっして、権利の前提として要求するものではありません。あなたは権利を、既に Creative Commons と GPL ライセンスのもとで得ています。ソースツリーの、FAQ.txt ファイルに、現在進行中の翻訳の一覧があるので見て下さい。私は、少なくても1つの章が完全に翻訳されたならば、翻訳が「進行中」であるとみなします。

この節の最初に述べたように、私はこの本の編集者です。しかし、あなたが貢献するなら、これはあなたの本にもなります。さて、では、2章、前書き、です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、全訳です。

は、長いので、別ページを参照。

は、長いので、別ページを参照。

付録 H クレジット

H.4 初出

  1. 16ページ、2.4節(“What Makes Parallel Programming Hard?”)は、最初に、Portland State University Technical Report に載せられました。

  2. 118ページ、6.5節(“Retrofitted Parallelism Considered Grossly Sub-Optimal”) は、第4回 USENIX Workshop on Hot Topics on Parallelism 。

  3. 179ページ、9.3.2節(“RCU Fundamentals”) は、Linux Weekly News。

  4. 189ページ、9.3.3節(“RCU Usage”)は、Linux Weekly News。

  5. 202ページ、9.3.4節 (“RCU Linux-Kernel API”)は、Linux Weekly News。

  6. 295ページ、12章(“Formal Verification”)は、Linux Weekly News。

  7. 465ページ、付録C.7 (“Memory-Barrier Instructions For Specific CPUs”)は、 Linux Journal 。

  8. 479ページ、付録D.1 (“Sleepable RCU Implementation”)は、Linux Weekly News。

  9. 488ページ、付録D.2 (“Hierarchical RCU Overview”) は、Linux Weekly News。

  10. 557ページ、付録D.4 (“Preemptible RCU”)は、Linux Weekly News。


は、全訳です。

は、全訳です。


以上