読者です 読者をやめる 読者になる 読者になる

森理 麟(moririring)のプログラマブログ

ゲームプログラマ森理 麟がのプログラムの話題を中心に書くブログです。

クッキーツイートの高速化 その17 インデクストラブル #CookieToEat

←気をつけろ!数字の順には進まない

前回マルチコア化はループの置き換え1行と言いました。

しかし、BackgroundWorkerで考えるとReportProgressの数は正しく渡りません。

これはマルチコアでのループのまわり方が順番に増えていくのでは無いからです。

例えばループを10回する場合を考えてみましょう。


通常であれば1の次は2、2の次は3です。当たり前です。

しかし、マルチコアは複数同時に処理するため、インデックスをコア毎に割り当てます。

1つ目のコアが1〜3,2つ目のコアが4〜6,3つ目のコアが7〜8,4つ目のコアが9〜10と言った感じです。

しかも、それらが非同期に実行されます。


だからインデックスナンバは1,4,7,9といった感じに渡されます。

もちろん1コア1つと言った規則性もありません。

1,2,4,7,9かもしれないし、1,2,4,5,7,9かもしれません。

つまりループのインデックスでは進行状況は表せないと考えるべきです。


そこでループ側のインデックスナンバーを渡すのではなくて、

受けて側にグローバルなカウンタ変数を持つことで対応します。

ProgressChangedの方にグローバル変数を持って、カウントアップします。

初期化で0クリアを忘れずに。

static int conuter = 0;
private void button1_Click(object sender, EventArgs e)
{
    conuter = 0;
    backgroundWorker1.RunWorkerAsync();
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
    Parallel.For(0, 10, i =>
    {
        System.Threading.Thread.Sleep(1000);
        backgroundWorker1.ReportProgress(i);
    });
}
private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
    conuter++;
    toolStripProgressBar1.Value = conuter;
}
                                                                                                                                                                              • -

12月03日に「わんくま同盟 大阪勉強会 #46」があります。

C#アプリの高速化」というネタで森理も話します。

Microsoft関係の話題が多いですが、基本何でもありの勉強会です。

参加資格などもないので、勉強会にご興味のおありの方は是非遊びに来てください!