C++ で 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

を使っても良い。


Synchronized Queue を作る

読み出し用のカウンタと書き出し用のカウンタをそれぞれSemaphoreで管理する。

    Cerium/TaskManager/kernel/ppe/SynchronizedMailManager.cc
    Cerium/TaskManager/kernel/ppe/SynchronizedMailManager.h

を使っても良い。


Synchronized Queue のtest 1

送信Thread一つ、3つのThread受信Threadを用意する。

受信Threadaにそれぞれ5つのデータを送り、順に受けとって終了することを確認する。終了データかどうかの判定を用意し、終了データが来たら受信Threadを停める。

pthread_thread_join で終了を待つ。

正しくデータを受信して終了することを確認せよ。


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個以上になるように分割する。

台数効果をグラフで示し、分割方法について考察せよ。


Shinji KONO / Tue Jan 20 13:18:42 2015