C++ とJava で Thread Pool を自分で作る
Menu
Synchronized Queue を自分で作る
Java の Blocking Queue のAPIを参考にしながら、
put takeを持つ複数のthreadからアクセスして正しく動く syncrhonized queueを作る。
Semaphoreを作る
Semapore は排他制御されたカウンタを持ち、PとVの二つの操作を持つ。これをpthread_mutex_lockとpthread_cond_wait で作成する。
P カウンタを増やす。カウンタを待っているSemaphoreがいたら、それを起こす V カウンタを減らす。ゼロだったら待ちに入る。http://www.cr.ie.u-ryukyu.ac.jp/hg/Game/Cerium の
Cerium/TaskManager/kernel/ppe/Sem.cc Cerium/TaskManager/kernel/ppe/Sem.hを使っても良い。
Java で Atomic / wait / notify を使って、同様のものを作成する。(Project は gradle project とすること)
Synchronized Queue を作る
読み出し用のカウンタと書き出し用のカウンタをそれぞれSemaphoreで管理する。
Cerium/TaskManager/kernel/ppe/SynchronizedMailManager.cc Cerium/TaskManager/kernel/ppe/SynchronizedMailManager.hを使っても良い。
Java で同様のものを作成する
Synchronized Queue のtest 1
送信Thread一つ、3つのThread受信Threadを用意する。受信Threadaにそれぞれ5つのデータを送り、順に受けとって終了することを確認する。終了データかどうかの判定を用意し、終了データが来たら受信Threadを停める。
pthread_thread_join で終了を待つ。
正しくデータを受信して終了することを確認せよ。
Java のSynchronizedQueue を Java Pathfinder で適切なassertを用意してテスト見よ。
Option
以下は選択問題です。
taskの作成
iからi+jの間の素数の個数を見つけるtaskを作る。2と3から√(i+j)までの奇数で順々に割って割り切れたら合成数、割り切れなかったら素数という簡単なtaskにしよう。素数の個数を返す関数 long countPrime(long i, long j) を作成せよ。
Taskの投入
Taskの引数を構造体にして、それをSynchronizaed Queueに渡す仕組みを作る。構造体は毎回mallocするか、前もってまとめて作っておく。今回は再利用する仕組みは作らない。
Taskの実行
worker thread では Queue から Taskを取り出し、countPrime で実行する。worker thread毎にに素数の数の和を格納し、それを取得する方法を用意する。
findPrimeの並列化
必要な worker thread を複数作成し、それに Synchronized Queue 経由で Task を投入し並列実行させる。実Core数に対応させた worker thread の数を変化させて、台数効果(並列実行でどれくらい高速になったか)を測定する。
素数の分布は1/nになると言われている。また、数字が大きくなるほど、素数判定に時間がかかる。これを考慮してTaskを分割する。
Taskは、それぞれのworker thread毎に16個以上になるように分割する。
台数効果をグラフで示し、分割方法について考察せよ。