以下は JE2BWM ほかが作成した翻訳 です。 原文は University of California より GFDL で配付されており、 この翻訳も GFDL に従います。
原文: Client scheduling   (翻訳対象の更新日付は 10:15 PM UTC, June 21 2006 です)。

クライアントでのスケジューリング

boinc.gif
(英語のみ)

 

この文書では、 BOINC コア・クライアント内の相互に関連する以下の3つの部分について記述しています。
CPU スケジューリング方針
走行可(後述参照)のリザルトの集合の中で、どれを実行させるべきか。 BOINC は通常 NCPUS 個のリザルトを同時に計算します。 ここで、NCPUS とは CPU の物理的個数(hyperthreading も勘定に入れます) あるいは、 参加者が ジェネラル・プレファレンスで指定した「max_cpus」の値のいずれか小さい方の値です。
CPU スケジュールの執行
スケジュールを実際に実施する(タスクを中断したり再開する)のは何時でしょうか? ときには、アプリケーションの実行を中断する前に、チェックポイントまで待つほうが望ましいこともあります。
仕事獲得の方針
コア・クライアントは、いつプロジェクトに仕事をもらいに行くべきか、 どのプロジェクトからもらうべきか、 そして、どれだけの量の仕事を獲得するべきか。

上述の方針の目標は、以下のとおりです(重要なものの順です)。

  1. リザルトを報告期限内に完了させて報告すること。 (期限を過ぎて報告した場合、そのリザルトはプロジェクトにとって価値がないこともあるので、 功績(credit)が付与されないことがあります)。
  2. NCPUS 個あるプロセサは、常に仕事があるようにすること。
  3. どんな時点においても、コンピュータには充分な仕事があり、少なくとも min_queue 日 の間、(値 min_queue は、参加者のプレファレンス(好みの設定)で決まります) NCPUS 個のプロセサが忙しくなるようにすること。
  4. プロジェクトごとの資源占有率が長期的に見て尊重されるようにすること。
  5. コンピュータが複数のプロジェクトに参加させられている場合には、 プロジェクト間の実行割り当てがなるべく頻繁に入れ代わること (頻度は参加者の指定した 'CPU scheduling period' というプレファレンスに従う)。
  6. 指定されたスケジューリング期間(scheduling period) に比べてあまりにも短い間隔で切り替えをプロジェクト間で起こさないようにすること。 これができなくて、かつ、「中断するアプリケーションをメモリ上に保持」というプレファレンス 訳注4を使わない場合には、 ある種のアプリケーションはチェックポイントからの回復に多大な時間を消費し、 多くの CPU 時間が無駄になります。

以前の版の BOINC では、参加しているプロジェクトあたり最低1つのリザルトを保持するよう試みていました。 そして、それらの全プロジェクトの間で重みづけしたラウンド・ロビン方式の CPU スケジューリングを実施しようとしていました。 いくつかのシナリオ(コンピュータが遅い場合、参加プロジェクトが多い場合、 報告期限まで余裕がない場合、および、これらの組合せのシナリオ)では、 すべてのリザルトで報告期限を守れないこともあり得ました。 新しい方針では、この問題点を以下のように解決します。

考え方と用語

柱時計 CPU 時間(wall CPU time)

柱時計 CPU 時間 とは、プロセスが OS から見て走行可能状態(runnable)だった経過時間(柱時計で測った時間)です。 実際の CPU 消費時間はこの値より小さいことがあります。 たとえば、 そのプロセスでペイジングが多量に発生した場合や、他の( BOINC でない) 仕事が同時に走っていたという場合にそうなります。

BOINC は、柱時計 CPU 時間をもって、CPU 資源の使用状況の指標とします。 柱時計 CPU 時間のほうが、ペイジングを起こすアプリケーションの場合、より公平です。 さらに、実 CPU 消費時間の測定は、アプリケーションが正しくその値を報告することに依存しますが、 アプリケーションは正確に答えないかもしれません。

正規化された CPU 時間

リザルトの 正規化された CPU 時間(Normalized CPU time) とは、 以下を考慮に入れて、リザルト計算完了までの柱時計時間を推定した値です。

ただし、対象のプロジェクトの資源占有率は考慮に入れません。

プロジェクトごとに正規化された CPU 時間

リザルトの プロジェクトごとに正規化された CPU 時間(Project-normalized CPU time) とは、 リザルト計算完了までの柱時計時間を推定した値であって、 上述の考慮を入れた上、さらに対象プロジェクトの資源占有率が 他の走行可なプロジェクトとの間でどのような比率になっているのかも考慮に入れたものです。

スケジューラ RPC 要求 に含まれる 'work_req' 要素は、 プロジェクトごとに正規化された CPU 時間を単位に表現されます。 どのような大きさの仕事を送るか決めるときに、 スケジューラはそのプロジェクトの資源占有率が全体に占める割合と、 その計算機の「on-fraction」および「active-fraction」を考慮する必要があります。

例をあげましょう。 ある計算機は 1 GFLOPS の CPU 群をもっていて、 対象プロジェクトの資源占有率が全体に占める割合は 0.5、 その計算機の 「on-fraction」は 0.8、「active-fraction」は 0.9 とします。 すると、CPU ごとの期待される処理速度は、以下のとおりです。

(1 GFLOPS) * 0.5 * 0.8 * 0.9 = 0.36 GFLOPS
この計算機が、プロジェクトごとに正規化された CPU 時間で、 1000 秒の長さの仕事を要求したとすると、スケジューラは 少なくとも 360 GFLOP の長さの仕事を送るべきです。

リザルトの状態

リザルト R が走行可(runnable) であるというのは以下の場合です。 R が ほぼ走行可(nearly runnable) であるというのは以下の場合です。

プロジェクトの状態

プロジェクト P が走行可(runnable) であるというのは以下の場合です。 プロジェクト P がダウンロード中(downloading) であるというのは以下の場合です。 プロジェクト P が仕事獲得可能(fetchable) (つまり、仕事獲得の方針で、そのプロジェクトから仕事を取り出すことが許される状態) であるというのは以下の場合です。 プロジェクト P が 通信制限状態(latency-limited) であるとは、以下の場合です。 プロジェクト P が潜在的に走行可(potentially runnable) であるというのは以下の場合です。 ということは、クライアント側で知る限りでは プロジェクト P のために望むなら仕事ができるということです。

負債(Debt)

直感的に言えば、プロジェクトに関する「負債(debt)」とは、 スケジューラが対象のプロジェクトにどれだけ仕事を与える責務があるかを示すものです。 その値は他のプロジェクトとの間の相対的な値です。 BOINC は2つの型の負債の概念を使っています。 両者とも、プロジェクトの集合 S について定義されます。 どちらの場合でも、負債の値は下記のように定期的に計算し直されます。 短期の負債(Short-term debt) という指標が CPU スケジューラによって使われます。 この値は、走行可の状態にあるプロジェクトの集合について、調整された値です。 短期の負債の最低値がゼロになるように、かつ、最大値が 86400(つまり、1日) を越えないように正規化されます。

長期の負債(LTD:Long-term debt) という指標が、仕事獲得の仕組みで用いられます。 この値は、全てのプロジェクトに対して定義された値であり、 潜在的に走行可の状態にあるプロジェクトの集合について、調整されます。 すべてのプロジェクトにわたり、長期の負債の平均値がゼロになるように正規化されます。

ラウンド・ロビンの模擬

ほぼ走行可のリザルトの集合に対して、重みづけしたラウンド・ロビン・スケジューリングの模擬をします。 この結果を、CPU スケジューリングと仕事獲得の方針で使用します。 この模擬は、「on-fraction」と「active-fraction」を考慮に入れます。 以下の出力を出します。

下記の例では、プロジェクト A と B がそれぞれ資源占有率 2 と 1 をもっています。 このコンピュータには、2つの CPU があります。 時刻 0 から 4 まで、3つのリザルトすべてが同じ重みでスケジュールされて走ります。 時刻 4 に、リザルト A2 が終わります。 時刻 4 から 8 では、プロジェクト A は資源を使える割合が 0.5 だけになっています。 というのは、A は1つしかリザルトをもっていないからです。 時刻 8 で、リザルト A1 が終わります。

この例では、shortfall(A) は 4で、shortfall(B) は 0、total_shortfall は 2 です。

CPU スケジューリングの方針

この CPU スケジューラは、2つの方針を使いわけます。 報告期限を超過する恐れがあるリザルトについては、期限余裕最短を優先 (EDF: earliest-deadline-first) という方針を使って CPU を割当てます。 そしてまだ別の CPU が使えれば、上記以外のプロジェクトについて 重みづけのあるラウンドロビン方式を適用します。 こうすれば、クライアントは超過しかねなかった期限を守ることができ、なお、 長期にわたる資源占有率の指示を尊重して動作することができます。 このスケジューリング方針は以下のように記述できます。

  1. 各プロジェクトの「想定負債額」の値を その短期の負債として設定します。
  2. deadlines_missed(P)>0 を満たすプロジェクト P であって、 それらの中でもっとも厳しい報告期限がついた走行可のリザルトをもつプロジェクトを P とします。 リザルト R を、P の中でもっとも厳しい報告期限がついた走行可のリザルトで、 かつ未だスケジュールされていないものとします。 同様のものが複数あったときは、 リザルトの配列の中でインデックスが小さいものを選びます。
  3. 上記のような リザルト R が存在するなら、その R をスケジュールし、 P の想定負債額を減らし、deadlines_missed(P) も減らします。
  4. まだ CPU があって、別のプロジェクト P で deadlines_missed(P)>0 のものがあれば、 1 に戻ります。
  5. 全ての CPU に仕事がスケジュールされたら、おしまいです。
  6. 現在 走行中のリザルト R があって、まだ CPU スケジューリング期間より 短い時間しか走っていなければ、その R をスケジュールし、ステップ 5 へ行きます。
  7. 最大の想定負債額をもつプロジェクト P を見つけて、P の走行可なリザルトを1つ選びます。 (すでに走っているものがあればそれを選択し、 さもなくば、プロジェクトから受け取った順番で言って一番古いものを選びます)。 そのリザルトをスケジュールします。
  8. P の想定負債額を、「期待する分配時間」だけ減らします。 (期待する分配時間(expected payoff)とは、 スケジューリング期間を、NCPS(CPU 個数)で割ったものです)。
  9. ステップ 5 へ行く。

この CPU スケジューラが走るのは、リザルトの計算が完了したとき、 参加者が指定した仕事期間の終了点に達したとき、 新しいリザルトが走行可の状態になったとき、そして、 参加者がユーザインタフェースを通じて何らかの操作をしたとき (たとえば、プロジェクトあるいはリザルトの一時停止・再開をしたとき) です。

CPU スケジュールの執行

この CPU スケジューラは、どのリザルトを走らせるべきかを決定しますが、 その判断を実施する役割は負っていません。 実施するのは別の スケジュール執行関数(scheduler enforcement function) です。 CPU スケジューラは結論を出したところで、これらを呼びます。 X を 現在 走行していないがスケジュールされたリザルトの集合とします。 Y を 今回はスケジュールされなかったが、現在 走行しているリザルトの集合とします。 T を スケジューラが最後に走った時刻とします。 スケジュールの執行方針は以下のとおりです。

  1. X のあるリザルト R について、もし deadline_missed(R) であるならば、 Y の中のリザルトを1つ中断し、その R を走らせます。 (中断するリザルトは、チェックポイント後、柱時計で測った CPU 時間がもっとも少ないものを選びます)。 必要ならこれを繰り返します。
  2. Y の中に 時刻 T 以後にチェックポイントを書き出したリザルトがあれば、 その R を中断して X の中のリザルトを1つ走らせます。

仕事獲得の方針

プロジェクト P が仕事超過(overworked) であるとは、

を満たすことであると定義します。

この条件が満たされるのは、P のリザルトが EDF モードにおいて走る場合です。 (極端な場合としては、とても LTD(長期の負債) が大きな負数であったプロジェクトから離脱した場合があります)。 この仕事獲得の方針では、仕事超過の状態にあるプロジェクトには仕事を取りに行かせません。 これによって、間近な報告期限の仕事をもっているプロジェクトが、 CPU 時間の占有率を越えてもさらに仕事を取り出すことを防ぎます。

仕事獲得の方針においては以下の関数を使います。

frs(project P)
仕事獲得可能(fetcharable)プロジェクトに占める、プロジェクト P の資源占有率の割合。

この仕事獲得方針のための関数は、数分おきに(および必要に応じて) スケジューラ の RPC ポーリング関数から呼ばれます。 この関数は、変数 P.work_request_size を各プロジェクト P ごとに設定します。 その値は、PIへのスケジューラ RPC を発行するとしたらどれだけの仕事を要求するかを、 単位を秒として表現したものです。 その値は以下のように計算します。

for each project P
    if  P が一時停止状態(suspended)、通信延期状態(deferred)、
        仕事超過状態(overworked)、あるいは、新しい仕事の禁止(no-new-work)
          のいずれかならば、
        P.work_request_size = 0
    else
        P.work_request_size = shortfall(P)

if total_shortfall > 0
    if すべてのプロジェクト(P)について P.work_request_size==0 ならば、
        for each project P
            if  P が一時停止状態(suspended)、通信延期状態(deferred)、
                仕事超過状態(overworked)、あるいは、新しい仕事の禁止(no-new-work)
                のいずれかならば、
                continue
            P.work_request_size = 1

    if すべてのプロジェクト(P)について P.work_request_size==0 ならば、
        for each project P
            if  P が一時停止状態(suspended)、通信延期状態(deferred)、
                あるいは、新しい仕事の禁止(no-new-work) のいずれかならば、
                continue
            P.work_request_size = 1

    P.work_request_size>0 である P に対して、
        P.work_request_size を正規化します。 つまり、合計が total_shortfall
        になり、それぞれの占める割合が P.resource_share に比例するように正規化します。 

CPU を散発的にしか使わないプロジェクトでは、 プロジェクト P が 走行可能状態に近い(nearly-runnable)訳注5 リザルトをもっていなければ P.work_request_size を 1 に設定し、さもなくば 0 に設定します。

スケジューラ RPC の仕組みは、サーバへ接続するプロジェクトを色々な理由で選択することがあります。 参加者が要求したり、トリクル・アップ・メッセージが突出している場合、 あるいは、報告期限を超過した計算結果がある場合です。 このようなケースでサーバに接続するときも、そのプロジェクトに対して仕事を要求します。 以上の場合ではないなら、RPC の仕組みは下記の条件をみたすプロジェクト P に仕事を獲得しに行かせます。

P.work_request_size>0 かつ、
P.long_term_debt + shortfall(P) が最大のプロジェクト
注意: P.work_request_size は、正規化された CPU 時間を単位に表現しますから、 実際の仕事要求の値 (これはプロジェクトごとに正規化した CPU 時間を単位に表現)は、 P.work_request_size の値を 走る可能性のあるプロジェクトに占める対象プロジェクト P の持つ資源占有率の割合で、 分割したものになります。

スケジューラの仕事送出の方針

注意: 以下に記述された内容はまだ実装されていません。 また、上述の方針とも独立なものです。

スケジューラは初めから報告期限を守れそうもないリザルトを送りつけるべきではありませんし、 すでにクライアントが持っているリザルトが期限を守れなくなるようなリザルトも送るべきではありません。 これを実現するため以下のようにします。


シナリオの記述

スケジューリングのシナリオを記述する際には、下記の記法を用いることを勧めます。 (時の単位は、時間(hours)です)。

P(C, D, R)

これは以下の性質を持つあるプロジェクトを意味します。

個々のシナリオは、プロジェクトの一覧、および、下記の追加パラメタで記述されます。 シナリオ記述の例はたとえば以下のようになります。
P1(1000, 2000, .5)
P2(1, 10, .5)
NCPUS=4

シナリオ集

シナリオ 1

P1(0.1, 1, .5)
P2(1, 24, .25)
P3(1, 24, .25)
NCPUS = 2
leave_in_memory = false
cpu_scheduling_period = 1
典型的には、どちらか1つの CPU が P1 の 6分かかるタスクを処理します。 もう1つの CPU は、P2 と P3 の仕事を切り替えて処理します。 重要なのは、スケジューラが P2 と P3 のタスクのそれぞれを スケジューリング期間全般にわたって走らせることです。 「負債」の考え方に正確に合わせてスケジューリングすると、6分ごとに毎回、 P2、P3の間で切り替えを起こすという結果になりますから、 P2 と P3 はそのたびごとにチェックポイントから再開せざるを得ないでしょう。 いくつかのアプリケーション(例: Einstein@home) では、 チェックポイントから再開するために数分の処理が必要です。 ということは、このシナリオでは片側の CPU の時間の大半を無駄にしてしまうことになります。

 


(訳注1): min_queue
次にサーバへ接続するまでの時間に相当するらしい。
(訳注2): leave_in_memory
中断された(preempted)ときに、アプリケーションをメモリ上に残すか否かの条件。
(訳注3): cpu_scheduling_period
クライアント内のローカルスケジューラがスケジューリングする時間の細かさの単位。
(訳注4): 中断するアプリケーションをメモリ上に保持
原文は remove processes from memory という言い回しになっていますが、 稼働しているプレファレンスの設定画面では、Leave applications in memory while preempted? という表現になっています。
(訳注5): 最短 RPC 時刻 (minimum RPC time)
RPCを出すことを許すもっとも早い時期という意味。 スケジューラ RPC タイミングと再試行ポリシー を参照のこと。
(訳注6): CPU 効率(CPU efficiency)
この値は、 BOINC アプリケーションが走行中に与えられた CPU 時間が 柱時計時間のうちいかなる割合を占めていたかを平均した値のことです。 重たい計算を BOINC 以外に同時にこなしているシステムでは、この値は 1 より小さくなります。 BOINC のニュース保管庫 June 24, 2005 を参照。

BOINCの訳のメインページに戻る | (原文のメインページに戻る)
 

最終更新時刻 00:50:39, 2006年08月12日(JST)
Copyright © 2012 University of California. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation.
Copyright © 2012 Komori Hitoshi(je2bwm at jarl.com). Japanese translation from English web pages on BOINC. Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation.