質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Q&A

解決済

8回答

3814閲覧

マルチスレッドプログラミングの使い道

strike1217

総合スコア651

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

マルチスレッド

マルチスレッドは、どのように機能がコンピュータによって実行したのかを、(一般的にはスレッドとして参照される)実行の複合的な共同作用するストリームへ区分することが出来ます。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

1グッド

4クリップ

投稿2018/02/16 10:19

編集2018/02/16 14:09

マルチスレッドプログラミングの使い道についてなのですが・・・

自分は、長らく「マルチスレッド = 高速化」と考えてきたのですが、なんだか違うような気がしてきました。

マルチスレッドは高速化を保証するものですか?
しかし、スレッドの実行はカーネルのプロセススケジューリングアルゴリズムによって管理されています。

前回の質問でraccyさんが言っている事と重なるのですが・・・
スレッドセーフな関数について
同時に一つのスレッドしか動かないという部分ですね。
これはつまり、時間的に重なる部分だけが高速化されるということになると思います。

同時に重なることがなく時分割で複数のコアにスレッドが割り当てられた時と1つのプロセスを比較的長い時間コアに割り当てるのでは性能に差が出ないという考えです。

複数のコアに同時に割当られた時のみ高速化される。という意味ですね。(効果が薄いような・・・)

これは、カーネルのスケジューリングアルゴリズムに従うため確率的なものですよね??

マルチスレッドは確率的に速度向上が期待できますよ・・・という程度の話では?

性能の上限については以下を
アムダールの法則
ある一点に到達するとそれ以上コアを増やしても性能は向上しないという上限ですね。

私の持っている本にこうあります。

GUIライブラリでは、大部分の関数は特定のスレッドからのみ呼び出されることになっており、これはイベントスレッドと呼ばれる。

このように実装することで、GUIライブラリ内のコードが内部データ構造に対する全てのアクセスをロックするコストを免れている。

イベントスレッドというのは初めて知ったのですが、要は**マルチスレッドで組む理由は高速化以外に何があるのか??**という疑問です。
つまり具体的な使い方です。

またマルチスレッドの最も優れている点を教えてください。
(上記にも書いたのですが、最も優れている点は本当に高速化なのかぁ?という疑問ですね。)

「追記」
マルチプロセス化を行う理由
マルチプロセスと書いてあるのですが、マルチスレッドでも同じ事だと思います。
セキュリティという観点もあるようですね。

SatoshiMashino👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

himazin.blm

2018/02/20 09:10

追記部分で挙げられているページの内容は、マルチスレッド処理だとCPU時間を100%までしか使えないところを、マルチプロセス処理化することで100%以上使えるようにする (4coreCPU環境だと400%まで使える) ことによるパフォーマンス向上と、マルチプロセス処理では並列で動作している別プロセスのメモリ空間にアクセスさせることが、やりたくてもできなくなることによるセキュリティ向上という話ですので、内容としてはだいぶ異なります。
strike1217

2018/02/20 11:08

そうなんですね。マルチプロセスもマルチスレッドも大差ないものだと思っていましたが・・・パフォーマンス向上には随分と差があるんですね。全部は読んでいなかったので失礼しました。
guest

回答8

0

ベストアンサー

マルチスレッドは高速化を保証するものですか?

違います。よく理解して使わなければ、むしろパフォーマンス低下につながります。

マルチスレッドで組む理由は高速化以外に何があるのか??

高速化以外の目的で使うことの方が圧倒的に多いです。マルチスレッドを高速化でしか使わないのなら、マルチ(コア)CPUでなければ意味がありませんが、世の中マルチ(コア)CPUだけではありませんから。

マルチスレッドで組む一番の理由は、複数のタスクを同時にこなす処理を自然に書けるということです。

どういうことかというと、マルチスレッドの概念がなかった頃(Windows 3.1とか)は、複数のタスクを同時にやろうとする場合、タスクを細切れにしてちょっとずつ交互に処理する、などという非常に面倒くさくてバグりやすい方法で行っていました。例えば、大量のデータをファイルに書き込む際、一定のバイト数を書き込んだらいったん書き込み処理は中断して、途中経過を画面に表示させてから、キャンセルボタンをチェックして押されていなければ、ファイル書き込みを再開し、一定のバイト数を書き込んだらまた中断して……、というのをデータを書き終えるまで繰り返します。

マルチスレッドなら、このような面倒なことはせず、UIスレッドとは別にファイル書き込みスレッドを作って、そっちはそっちでファイル書き込みに注力し、適当なタイミングで経過をUIスレッドで表示させる、ということが自然に(簡単に)書けます。

またマルチスレッドの最も優れている点を教えてください。

比較対象が明示されていないので、なんとも答えようがありません。状況を鑑みてマルチスレッドを使うべきと思ったらマルチスレッドを使います。

投稿2018/02/16 12:28

catsforepaw

総合スコア5938

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

strike1217

2018/02/16 13:55

> 高速化以外の目的で使うことの方が圧倒的に多いです そうなんですね! 高速化目的がメインだと思っていました。 役割分担がしやすい・・・と考えれば良いんですかね。
catsforepaw

2018/02/16 14:29

> 役割分担がしやすい・・・と考えれば良いんですかね。 そんな感じですね。もう少し言葉を追加するなら「それぞれの役割に注力したコードが書けるので、役割分担が明確にできる」と言い換えることができます。 高速化については、マルチスレッドだから高速化できるというよりも、マルチスレッドにより複数同時処理が簡単に書けるようになったことで、時間のかかる計算を複数に分割して同時に処理するというコードが書きやすくなり、それをマルチ(コア)CPUで応用することで高速化につなげる、ということです。
strike1217

2018/02/16 15:19

なるほど! わかりました。
guest

0

こんにちは。

catsforepawさんが既に回答しているので、あまり書くこと無いのですが、この見解に賛成の人が他にも居ることを示すためにも回答します。(意外に少数派なので)

別の表現をすると複数のシーケンス制御を行う時、スレッドは非常に有用です。
例えば、ちょっと複雑ですが、

①メイン:A処理 → B処理 → B処理完了後、その結果でA処理へ戻るか、C処理へ進む。
②A処理:X処理 → A1処理開始 → A1処理完了待ち
③B処理:X処理 → X処理の結果で、B1処理、B2処理、B3処理のどれかを実行
④X処理:X1処理開始 → X1処理完了待ち → X2処理開始 → X2処理完了待ち

のような①の処理を複数並列処理したい時、上記の①のシーケンス毎にスレッドを割り当てるとたいへん楽にプログラムできます。待ちのあるX処理が複数のところから呼ばれるのでスレッドがないとなかなか苦労することになります。

単純なシーケンス制御の時は状態マシンコールバックにより容易に処理できるため、スレッドの効果が見えにくいのですが、複雑なシーケンス制御には非常に効果的です。

投稿2018/02/16 13:18

Chironian

総合スコア23272

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

要はマルチスレッドで組む理由は高速化以外に何があるのか??という疑問です。

レスポンススタイムの向上だと思います。「高速化」ではなくてむしろそちらがメインかと。

以下の記事の「マルチスレッド化で速度向上が期待できる場面は限られている」のセクションを読んでください。

第1回 マルチスレッドはこんなときに使う (2/2)
http://www.atmarkit.co.jp/ait/articles/0503/12/news025_2.html

投稿2018/02/16 10:49

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

strike1217

2018/02/16 11:27

読んでみますわ。
strike1217

2018/02/16 12:13

すでに高速化のための技法というより、インターフェース実装の一部のような感じになっているような気がしますね。
退会済みユーザー

退会済みユーザー

2018/02/16 12:19

シングルコアで高速化できるはずはない(逆にスレッド切り替えのオーバーヘッドで遅くなる)ということは理解されたでしょうか? 「すでに」という言葉は当たってないですよ。
strike1217

2018/02/16 12:21

ああ、そうですね。
guest

0

広義の高速性に含まれるかも知れませんが、

  • 単位時間あたりの計算量を増やす=>スループット向上
  • 何かが発生した際に速やかに反応する=>リアルタイム性の向上

の2つが「違うもの」と捉えますと後者はマルチスレッドで実現するとプログラムの構造が単純にできるという利点があると思います。

例えばGUIアプリは「ユーザーが何か操作したら即座に反応する」という方針で設計されるのが普通です。そのため「ユーザーが何か操作してもそれを無視して何かの計算に長時間(数ミリ秒以上)没頭すること」を避けようとします。しかしシングルスレッドでそういうルールを守ろうとすると「少なくとも数ミリ秒程度計算処理を行ったらそれをちょっと中断してユーザーがなにか操作していないかチェックする」なんてことをしなくてはなりません。長時間の処理の途中でそういうことを一々やるのはけっこうめんどくさい(※)ことです。

そこでGUIアプリケーションでは

  • ユーザー操作に反応する専用のスレッド(A)
  • 長くかかるような特定の計算処理に没頭するようなスレッド(B)

を並行して動かすことがよく行われます。もっとも(B)がCPUをぶんまわすような処理ですと質問者さんがおっしゃるようにOSがその合間を縫って(A)をスケジュールしてくれる確率が下がるため(A)の反応が鈍くなりがちで調子がわるくなります。

そういう場合でも(B)スレッドのスケジューリングのプライオリティーを下げることで許容範囲の動作を達成できることもあるかも知れませんけど。

いずれにせよ(※)のような面倒な設計をするのに比べるとスレッドを分けることですっきりと書けることがおおいのは事実と思います。

投稿2018/02/16 10:44

編集2018/02/16 11:36
KSwordOfHaste

総合スコア18394

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

strike1217

2018/02/16 11:29

マルチスレッドとGUIの組み合わせは良く聞きますよね。 GUIでよく使われるということなんですね。
guest

0

マルチスレッド化というのはちょっと低レイヤーすぎて大半のプログラマーには扱えないと思うので、普通は高レイヤーな非同期処理、もしくは勝手にタスク分割してくれるなにかが欲しいんだと思います。

非同期処理

他の方の回答はだいたいこれですかね?

現代のコンピュータはCPUやGPUでの演算は非常に高速ですが、メモリー転送速度やDisk I/Oは極めて低速です。こういった遅い処理の間CPU/GPUを遊ばせておくのは非常にもったいないです。

しかし手動で遊ばせないようにするのはcatsforepawさんの指摘の通り人間を卒業しないと無理です。

そこで非同期処理という概念を持ち出します。

もっとも古典的な非同期処理の利用法はCallback関数を用いるものです。つまり非同期に処理を行う関数Aに次に実行したい処理を行う関数Bを引数経由で渡します。

これは通称Callback地獄と言われるようにだいぶ可読性が下がってしまうのでPromiseと言われる、.then()にCallback関数を渡すことで見かけ上ネストが深くならないというやつがあります。

でもやっぱりCallback関数を書かないといけないし、変数の引き継ぎに問題があるので、coroutineというのが登場しました。async/await/yieldというキーワードをプログラミング言語側で用意して実質キーワードつけるだけでいい感じに書けます。JavascriptとかC#とかが対応していてC++も対応しそうです。

別な概念としてはchannelというのがあって、golangのおかげで知名度が上がっている気がします。

タスク分割

物理的にCPUのコアが複数あるとか、HTT(コアの中で使ってない演算器を利用して1コアなのに複数(普通2つ)の処理を同時に行う)とかで、本当に並列処理できるとき、勝手にタスクを分割して同時処理してくれると高速化できます。

これも手動で書くには辛さがあるのでOpenMPであったりとか、C++17で追加された並列対応のアルゴリズム関数群とかC#のLINQとかそういうのを使います。

投稿2018/02/17 16:14

yumetodo

総合スコア5850

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

strike1217

2018/02/17 16:19

「現代のコンピュータはCPUやGPUでの演算は非常に高速ですが、メモリー転送速度やDisk I/Oは極めて低速です。こういった遅い処理の間CPU/GPUを遊ばせておくのは非常にもったいないです。 」 この説明は非常に分かりやすいですね。
yumetodo

2018/02/17 16:23

GPUのメモリー(VRAM)と普通のメモリー(RAM)の間のメモリー転送の非同期化は紹介したような高レイヤーな手法が存在しないので人間を卒業しないと無理な離れ業が要求されてきたのですが、最近やっとそのへんをいい感じにする方法が出てきたらしいです(よく知らない)。
strike1217

2018/02/17 16:34

fmfm なるほど!こちらでも調べてみますわ。 高速化目的になるとマルチスレッドより1つ上の段階の話になるわけですね。 「マルチスレッドを複数のコアで応用する」こちらは高速化狙いなわけですね。
yumetodo

2018/02/18 04:50

>1つ上の段階の話になるわけですね。 ?
guest

0

openmpとopenMPIで考えると、openmpの方がコードを書くのがずっと楽です。
マルチプロセスとマルチスレッドで比較する時のメリットです。

並列化効率を出すためには演算律速のことを行う必要があります。

投稿2018/02/16 14:58

mkgrei

総合スコア8560

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

strike1217

2018/02/16 16:00

演算律速とはなんでしょうか??
mkgrei

2018/02/16 16:26

ファイルの書き込みなどはIO律速です。 CPU処理のところでボトルネックが来ている時に演算律速といいます。 ネットワークを通すと通信で律速となるとなることが多いです。 ただたとえば行列積といった計算がヘビーなところで演算律速となります。
strike1217

2018/02/17 11:00

ああ! ボトルネックですね。
guest

0

Webアプリがシングルスレッドで動いてたらどうなるでしょうね。
処理を各スレッドに割り振るディスパッチャーとして動くスレッドは除きます。

1つ目のリクエストが来て、その処理を唯一のスレッドに割り当てます。
2つ目のリクエストが来ましたがスレッドは処理中なので、キューに貯めときます。
1つ目の処理が終わって唯一のスレッドがプールに戻ってきたので、2つ目の処理を割り当てます。
みたいなことになるんじゃないでしょうか。
あとの人たちは待たされすぎて遅いなんてもんじゃなくなってきますね。
マルチスレッドは、1つの処理の高速化というより並行処理のためのものだと思っています。

バッチ処理とかだったとしても、10秒かかる処理と20秒かかる処理を
シングルスレッドで行うと30秒かかりますが、2スレッドでやると20秒後には次の処理に進めますね。
そういう意味では高速化と言えるかもしれませんが、処理自体の速度が上がってるわけではないです。
実際はこんな単純な計算ではないので、スレッド生成時のオーバーヘッドや、
複数スレッドによってマシンパワーを食う分1つ1つの処理が完了するまでの時間は
シングルスレッドの時より長くなってるかもしれません。
それでも22,3秒で次に行けるならばマルチスレッドにする価値はあることになります。

ビッグデータをパラレルでさばくと速くなるか?
みたいな話しだと思いますが、きちんとコアがフル活動してるかどうかっていう
アルゴリズム依存の部分はあると僕も思いますね。

投稿2018/02/16 12:46

編集2018/02/16 13:05
root_jp

総合スコア4666

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

マルチスレッドはマルチタスキングを実現するための手段の一つです。

マルチスレッドで最も優れているところは、対マルチプロセスにおけるプロセス生成のオーバーヘッドがない点です。

「シングルスレッドからマルチスレッドに変更すると処理が高速化される」は往々にして間違いです。

投稿2018/02/16 12:12

編集2018/02/16 12:19
YouheiSakurai

総合スコア6142

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

strike1217

2018/02/16 12:21

> 「シングルスレッドからマルチスレッドに変更すると処理は高速化する」は往々にして間違いです。 あ!そうなんですね!
YouheiSakurai

2018/02/16 12:29

そうです。処理を高速化するためにマルチスレッド化する事は滅多にありません。 それよりも、あるタスクの実行最中に発生する待ち時間の間に、別のタスクを実行するためにマルチスレッド化するケースがほとんどです。
strike1217

2018/02/16 14:12 編集

ああ! 「あるタスクの実行最中に発生する待ち時間の間に、別のタスクを実行する」 なるほど!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問