第4回 並列処理プログラミングの基本用語
株式会社フィックスターズ
好田 剛介
2009/12/18
CPUの周波数の高速化競争が頭打ちになり、1コアにおける処理能力は限界となった。CPUの進化がマルチコア化に向かった結果、並列コンピューティングの門戸が開かれた(編集部)
「並列化されていないコードよりは速く」から始めよう
第2回「現代のプロセッサと並列実行」や第3回「プロセッサ別に見る並列アーキテクチャ」では、さまざまなプロセッサの構造について説明しました。
しかしながら、それらのプロセッサにおける並列実行の仕組みのすべてを利用して、 その性能を限界まで引き出すのは簡単ではありません。
そこで、今回から3回に分けて、並列処理プログラミングの第一歩として、「並列化されていないコードよりは速い」ことを目標に、簡単な並列プログラムを実際に書いていきます。
今回は、覚えておくべき用語を、実際にコードを動かしながら解説します。第5回と第6回では、スレッドを用いた並列プログラムと、ベクトル演算を用いた並列プログラムの2つを紹介します。
これらの手法は計算機内部での並列化を実現するものです。複数の計算機にまたがる並列プログラムについては、また別の機会に述べることにします。
今回のスレッドに関するプログラムは、Ubuntu 9.04 x86版とg++ 4.3.3、Boost c++ library 1.35.0で動作確認を行っています。ベクトル演算に関するプログラムは、Yellow Dog Linux 6.1とCellSDK 3.1で動作確認を行っています。
Boost C++ライブラリ
今回はスレッドを用いた並列プログラムとして、Boost C++ライブラリ(以下、Boost)を利用したマルチスレッドプログラムについて説明します。
Boostは、フリーで検証された移植性の高いC++のライブラリです。既存のC++標準ライブラリとの相性が良く、Boostのライブラリの内のいくつかは次期C++標準ライブラリの候補になっています。
例えば、Boost.Threadは、Boostのスレッドライブラリで、TR1として知られているC++の技術報告書に次期C++標準ライブラリとして候補に挙げられています。
このような移植性の高いスレッドライブラリを使用すると、プロセッサに依存しない並列プログラムを書くことができます。
基本的な用語を覚えよう―スレッド
手続き型プログラムでは、変数の読み書きをしたり、演算をしたり、関数を呼んだりしますが、このようなプログラム実行時における処理の流れをスレッドと呼びます。
従来のプログラムではスレッドは1つしかありませんでしたが、複数のスレッドを用意することで、データを共有しつつ複数の独立した処理の流れを扱えるようになります。このような複数のスレッドを扱うプログラムをマルチスレッドプログラムと呼びます。
これまではシングルコアのプロセッサが主流であったため、マルチスレッドプログラムを書いても1つのコアで複数のスレッドを処理することとなり、マルチスレッド自体のオーバーヘッドのために若干遅くなってしまいました。このような、見掛け上は並列のように見えるが実際には並列でないものを、疑似並列(pseudo parallel)と呼びます。
しかし、現在はマルチコアのプロセッサが広く使われるようになっていますので、マルチスレッドプログラムは高速化の有効な手段となります。
それでは、実際にマルチスレッドプログラムについて説明していきます。次のコードはエラーチェックなどを省いた単純なスレッドプログラムです。
#include <iostream> #include <boost/thread.hpp> void para_func(void) { for (int i = 0; i < 3; ++i) { std::cout << "0" << std::endl; } } int main(void) { boost::thread th(para_func); for (int i = 0; i < 3; ++i) { std::cout << "1" << std::endl; } th.join(); return 0; }
sample_boost_thread.cxxとして保存し、コンパイルします。
$ g++ sample_boost_thread.cxx -lboost_thread -o sample_boost_thread.elf
それでは実行してみましょう。
$ ./sample_boost_thread.elf 1 0 1 0 0 1
para_func関数で出力される0と、main関数で出力される1が混ざっていることから、並列に実行されていそうだ、ということが分かるかと思います。
では、本プログラムを行順に解説していきましょう。
このプログラムは実行されると、まずmain関数からスタートします。この時点では1つのスレッドのみが存在します。
main関数の14行目で、boost::threadクラスのthという変数をpara_funcという引数で定義しています。ここでmain関数が実行されているスレッドとは別の新たなスレッドが生成され、そのスレッド上でpara_func関数の実行が開始します。
この時点でmain関数が実行されているスレッドと、para_func関数が実行されているスレッドの2つのスレッドが存在することになります。
その後、main関数は18行目で1を標準出力に出力し、21行目のth.join()でpara_func関数が実行されているスレッドの終了を待ちます。それと同時にpara_func関数は8行目で0を標準出力に出力し、関数のリターンとともにスレッドを終了します。
このjoin関数による待ちを行わず、main関数がpara_func関数よりも早く終わった場合、para_func関数実行中にも関わらずプログラムが終了してしまうので注意してください。
これでスレッドの一番基礎的な部分は終了です。
1/2 |
![]() |
Index | |
並列処理プログラミングの基本用語 | |
![]() |
Page1 「並列化されていないコードよりは速く」から始めよう Boost C++ライブラリ 基本的な用語を覚えよう―スレッド |
Page2 基本的な用語を覚えよう―ミューテックス そのほかの基本的な用語 |
![]() |
Think Parallelで行こう! |
- プログラムの実行はどのようにして行われるのか、Linuxカーネルのコードから探る (2017/7/20)
C言語の「Hello World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。最終回は、Linuxカーネルの中では、プログラムの起動時にはどのような処理が行われているのかを探る - エンジニアならC言語プログラムの終わりに呼び出されるexit()の中身分かってますよね? (2017/7/13)
C言語の「Hello World!」プログラムで使われる、「printf()」「main()」関数の中身を、デバッガによる解析と逆アセンブル、ソースコード読解などのさまざまな側面から探る連載。今回は、プログラムの終わりに呼び出されるexit()の中身を探る - VBAにおけるFileDialog操作の基本&ドライブの空き容量、ファイルのサイズやタイムスタンプの取得方法 (2017/7/10)
指定したドライブの空き容量、ファイルのタイムスタンプや属性を取得する方法、FileDialog/エクスプローラー操作の基本を紹介します - さらば残業! 面倒くさいエクセル業務を楽にする「Excel VBA」とは (2017/7/6)
日頃発生する“面倒くさい業務”。簡単なプログラミングで効率化できる可能性がある。本稿では、業務で使うことが多い「Microsoft Excel」で使えるVBAを紹介する。※ショートカットキー、アクセスキーの解説あり
![]() |
||
|
||
![]() |
Coding Edge 記事ランキング
- ダントツで首位のPython、2位のC++との差が過去最大に 2025年5月版プログラミング言語人気ランキング
- Google、生成AIでアプリのプロトタイピングからデプロイまで支援する「Firebase Studio」を発表 フルスタックAIアプリをどう構築できるのか
- JetBrains、C/C++用IDE「CLion」の非商用利用を無料化 非商用ライセンスの注意点は?
- アジャイルのイテレーションを効率的に進めるためには? 5つの注意点を解説
- OAuthだけじゃない 現代のAPI開発者が知るべき「5つの基本戦略」(認証方式編)
- 生成AI時代は「Visual Studio Code」一択ではない? 注目の次世代コードエディタとは RedMonk
- VS Codeにもついに「持ち込みAI」時代が来た?──バージョン 1.99での変更点を紹介
- AWS、AIエージェントとの統合を支援する9つのMCPサーバを「AWS MCP Servers」として公開 オープンソースで提供開始
- Excelのオートフィルターで絞り込んだデータの件数と合計を関数で求める
- 右クリックメニューやサブメニューにマクロを登録/削除するには
- Pythonが依然独走、Kotlin、Ruby、Swiftが苦戦 TIOBEプログラミング言語ランキング
- VS Codeにもついに「持ち込みAI」時代が来た?──バージョン 1.99での変更点を紹介
- AWS、AIエージェントとの統合を支援する9つのMCPサーバを「AWS MCP Servers」として公開 オープンソースで提供開始
- OAuthだけじゃない 現代のAPI開発者が知るべき「5つの基本戦略」(認証方式編)
- Google、生成AIでアプリのプロトタイピングからデプロイまで支援する「Firebase Studio」を発表 フルスタックAIアプリをどう構築できるのか
- 開発者向けAIエージェント「Devin 2.0」正式発表、エージェントネイティブIDEと3つの新機能を搭載
- 「GitHub MCPサーバ」提供開始、MCPとは? VS Codeユーザーに何が便利なのか
- 「検証はあなたの仕事」 GitHub CopilotにおけるセキュリティのベストプラクティスをGitHubが初学者向けに解説
- 「Wasmer 6.0」が登場、ネイティブに近い速度でWebAssemblyを実行可能 主要な強化点は?
- VBAでファイル名や拡張子を取得する方法、特殊フォルダを取得する方法