こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

締切り済みの質問

Javaのスレッドとcpuのスレッド

javaのスレッドは各スレッドを少しずつ実行してあたかも同時に実行しているように見せかけているだけだと本で読んだことがあります。現在のcpuはi7 8700kだと6コア12スレッドになりますが、この場合どのような動きになるのでしょうか。
例えば12個のスレッドを使用したプログラムを実行するとpcが勝手に8700kの12スレッドに割り振って実行してくれるのか、それとも単にcpuの1スレッドでjavaの12スレッドを同時に動かしてるように見せかけるのか、cpuのスレッドとjavaのスレッドの関係がいまいち解りません。

投稿日時 - 2018-08-03 10:18:41

QNo.9524375

暇なときに回答ください

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(9)

ANo.9

>回答No.7 amanojaku1

例えばオカメの お面を作るのに6サイクルかかるとします。
1つ1つオカメの お面を作ると、いつも6サイクルかかりますが、ベルトコンベアなら最初の1個目は6サイクルかかりますが、2個目からは1サイクルづつでオカメの お面が完成します。
ただし、実際は そう単純ではなく、Stall(ストール:停止状態:実態はベルトコンベア上のオカメの お面の破棄)、Stall(ストール)以外のパイプライン・ハザード(パイプラインの停止状態:ベルトコンベアの停止状態)などがあり、理想どおりにはなりませんが。

投稿日時 - 2018-08-04 23:45:02

ANo.8

他の方も答えていらっしゃいますが、
CPUのスレッドとは、Hyper Threadingという名のCPUの論理コアのことを表しています。
Javaのスレッドは、java.lang.Threadクラスを用いて、
OSが管理しているスレッド機構にアクセスすることで、
同一プロセス上のメモリ空間を共有して、
プロセス間通信をせずに情報を伝達する機構です。

OSが管理しているスレッド機構では、
CPUに命令(とデータ)を投げる際、
高速に処理を行うために
L1~L3のキャッシュメモリに
データが残っているCPUコアに対して
命令を投げるようにします。
そのため、OS上の同一プロセス、同一スレッドの処理が
同一CPUコアで処理されることが多いです。

しかしながら、
どうしても命令を同一CPUコアに割り振ることができない場合に
別なCPUコア(とL1~L3のキャッシュメモリ)に
命令とデータを送る必要があり、
そのことを「コンテキストスイッチ」と呼び、
処理の遅くなる傾向を表す尺度の一つとなっています。

投稿日時 - 2018-08-04 23:29:27

ANo.7

>回答No.6 amanojaku1

ちなみにパイプラインとは、ざっくりと言うとベルトコンベア的な感じです。

投稿日時 - 2018-08-04 23:26:04

ANo.6

>回答No.5 amanojaku1

インテルCPU進化論 パイプラインで見るAtomの利点と限界
http://ascii.jp/elem/000/000/737/737249/

↑添付画像は上記ページより引用。
添付画像はIntel Atomのパイプラインで、「Execute」が実行ユニットになります。
Intel Atomの実行ユニットは下記のようになってるようです。

ALU(整数演算ユニット)x2
JEU(ジャンプ実行ユニット)x1
Shifter(シフト演算ユニット)x1
FPU(浮動小数点演算ユニット)x2
SIMD(Single Instruction Multiple Data)x2
※(Intel Atomでは)FPUとSIMDが同じユニットになってるぽいので、(Intel Atomでは)FPUとSIMDは排他利用かもしれません。

投稿日時 - 2018-08-04 23:18:17

ANo.5

>回答No.4 amanojaku1

>例えば論理コア(Hyper-Threading(Hyper-Tasking))は1コアで2Thread(Task)を実行し、使われてない(CPUの)実行ユニットを使って例えば約5%~20%程度の(CPUの)実行ユニットの使用率を向上させます(既に使用中の(CPUの)実行ユニットは使えませんが)。
>例えば約10%前後の回路の増加で、例えば約5%~20%程度の実行ユニットの使用率が向上するなら(コスト的な意味で)メリットが有る訳です。

(CPUの)特定の実行ユニットを2系統・装備し、「自分、他者」のThread(Task)で使用中でも、もう1系統の(CPUの)実行ユニットが使えるようになっている場合もあるようです(その分、回路も増加しコストも増加する)。
Intel Atomは((CPUの)実行ユニットの有効活用と言う側面もあるが)Stall(ストール:停止状態)の解消に論理コア(Hyper-Threading(Hyper-Tasking))を採用しているらしいです。
下記は残念なIntel Atomの解説ですが、CPUの基本の基本としては理解しやすいと思います。

インテルCPU進化論 パイプラインで見るAtomの利点と限界
http://ascii.jp/elem/000/000/737/737249/
http://ascii.jp/elem/000/000/737/737249/index-2.html
http://ascii.jp/elem/000/000/737/737249/index-3.html

投稿日時 - 2018-08-04 14:35:57

ANo.4

>cpuのスレッドとjavaのスレッドの関係がいまいち解りません。

まず、Hyper-ThreadingとJavaのThreadは全くの別物です。
Hyper-ThreadingはJavaで言う所のThreadではなく、論理コアです(Hyper-ThreadingはHyper-Taskingとかに読み替えて下さい)。
(Windowsなどでは)物理コアと論理コア(Hyper-Threading)は区別しないようです。
物理コア:2、論理コア(Hyper-Threading):2で(Windowsなどでは)合計4コアと認識されます。
例えば1コアでは約30%程度の(CPUの)実行ユニットしか使用されなかったとします。
例えば論理コア(Hyper-Threading(Hyper-Tasking))は1コアで2Thread(Task)を実行し、使われてない(CPUの)実行ユニットを使って例えば約5%~20%程度の(CPUの)実行ユニットの使用率を向上させます(既に使用中の(CPUの)実行ユニットは使えませんが)。
例えば約10%前後の回路の増加で、例えば約5%~20%程度の実行ユニットの使用率が向上するなら(コスト的な意味で)メリットが有る訳です。

>例えば12個のスレッドを使用したプログラムを実行するとpcが勝手に8700kの12スレッドに割り振って実行してくれるのか、それとも単にcpuの1スレッドでjavaの12スレッドを同時に動かしてるように見せかけるのか、

>回答No.2 amanojaku1

↑こちらで前述した記事ではJavaのThreadでは「物理コア、論理コア(Hyper-Threading)」を100%使い切ることは出来ないので「マルチコア・プロセッサ環境でその性能を十分に発揮できない」ので「もうこのような実装はやめたほうがよい」と説明している訳です。

投稿日時 - 2018-08-04 11:35:55

ANo.3

>回答No.2 amanojaku1

関係無いですが

IntelのSkylake&Kaby Lake世代のCPUにはハイパースレッディング有効でデータ欠損やプログラムエラーにつながる重大なバグがあると判明
https://gigazine.net/news/20170626-intel-skylake-kabylake-bug/

>バグ対象のSkylake・Kaby Lakeには、リリース目前のハイエンド向け新CPU「Core i9」シリーズを含む、Core-Xシリーズが含まれています。

↑「Skylake、Kaby Lake」だけでないことに注意して下さい。

ハイパースレッディングOFF無効化推奨 エラーでデータ破損の可能性 Skylake/Kabylake
http://osusumenewusedpc.seesaa.net/article/451221695.html

>4月か5月にはIntelから修正されたマイクロコードが登場していた様子

↑2017年5月頃までに販売された該当するCPUが搭載されているPCは危険と言うことに。

投稿日時 - 2018-08-04 09:59:19

ANo.2

知らない間に「Thread」は非推奨になっているようです(^_^;マジか?)

Java EE 7で並列処理がケタ違いに速くなる! 使いこなしのポイントは?──Java Day Tokyo 2013レポート
https://blogs.oracle.com/wlc/java-ee-7-java-day-tokyo-2013

>Java EE 7では、「Concurrency Utilities for Java EE」の導入により、マルチコア・プロセッサの能力を余すことなく引き出し、並列処理を格段に速く行えるようになる。

↑このJava EE(Enterprise Edition)はサーバー側の開発環境の話です。

>2004年にJava SE 5でConcurrency Utilitiesを導入。

↑このJava SE(Standard Edition)はクライアント(一般の個人のPC)側の開発環境の話です。

>2011年にリリースされたJava SE 7ではFork/Joinに対応。さらに、2014年にリリース予定のJava SE 8ではラムダ式をサポートし、これまで以上に並列処理が簡単に記述できるようになるという。

>「スレッド処理に関して、いまだにJavaの登場当初からのnew Thread(r).start(); などと書いているプログラムを多く見かけるが、もうこのような実装はやめたほうがよい」とアドバイスした。

>そこで現在、スレッドを直接生成する方法に代わって推奨されているのが、Java SE 5 から導入されたConcurrency Utilitiesである。Concurrency Utilitiesは並列処理の実装を簡素化するために導入されたAPIで、これを利用することによってスレッドのライフサイクル管理が簡単になるほか、スケーラビリティやパフォーマンスが大幅に向上するのだという。
>このデモでは、シングルスレッドやマルチスレッドのプログラムが256個のうち一部のプロセッサしか利用できないのに対して、Concurrency Utilitiesを使った場合は256個のプロセッサの負荷がほぼ同時に限界まで達し、瞬時に処理を終えることが確認できた。
>「Javaはパフォーマンスが悪いという声を聞くことがあるが、それは間違い。パフォーマンスが悪いのは、いまだに古いやり方でプログラムを書いているからにすぎない。Concurrency Utilitiesでマルチコア・プロセッサの能力をフルに使い切れば、Javaは驚異的なパフォーマンスを発揮する」

投稿日時 - 2018-08-04 00:47:13

補足

Concurrency Utilitiesですか。知りませんでした。回答ありがとうございました。

投稿日時 - 2018-08-04 09:59:33

ANo.1

CPUのスレッドもアプリケーションのスレッドも同じ意味です。

> 例えば12個のスレッドを使用したプログラムを実行するとpcが勝手に8700kの12スレッドに割り振って実行してくれるのか、それとも単にcpuの1スレッドでjavaの12スレッドを同時に動かしてるように見せかけるのか

CPUの12スレッド全てがアプリケーションに使用される訳ではありませんし、アプリケーションの各スレッドが完全に独立して動ける訳では無いので、完全にばらける訳ではありませんが、同時実行可能な処理であればある程度はばらけて動作します。

投稿日時 - 2018-08-03 23:08:48

補足

回答ありがとうございました。

投稿日時 - 2018-08-04 09:58:08

あなたにオススメの質問