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

Parallel Extensions to the .NET FX CTP (2)

.NET

id:NyaRuRu:20071130:p1 のあとちょこちょこ弄ってはいるのですが,確かに速度向上は Dual Core で 1.6 倍ぐらいですな.あくまでお気楽 qsort で,ですが.
XNA 勉強会でひげねこさんも強調されていましたが,現状の XNA なんかだと GC 周りのチューニングで 10 倍高速化,なんてのもありうるので,高々 2 倍とか 3 倍しかパフォーマンスが上がらない並列化は後回しで良いような気がします.コア数が 2 桁になってくるとだいぶ雰囲気違ってきそうですけど.まあ PLINQ の場合はソースコードが #if まみれ (OpenMP だと #pragma かな) にならないので,使わない積極的な理由もまた無いといえるかもしれません.
ちなみに付属サンプルの Partition メソッドをちょこっと弄ってもソート速度は 2 倍ちょっと良くなりました.

private static int Partition<T>(T[] arr, int low, int high) where T : IComparable<T>
{
    // Simply partitioning implementation

    int pivotPos = (high + low) / 2;
    T pivot = arr[pivotPos];
    Swap(arr, low, pivotPos);

    int left = low;
    for (int i = low + 1; i <= high; i++)
    {
        if (arr[i].CompareTo(pivot) < 0)
        {
            left++;
            Swap(arr, i, left);
        }
    }

    Swap(arr, low, left);
    return left;
}

これを以下のように書き換えます.

private static int Partition(int[] arr, int low, int high)
{
    // Simply partitioning implementation

    int pivotPos = (high + low) / 2;
    T pivot = arr[pivotPos];
    Swap(arr, low, pivotPos);

    int left = low;
    for (int i = low + 1; i <= high; i++)
    {
        if (arr[i] < pivot)
        {
            left++;
            Swap(arr, i, left);
        }
    }

    Swap(arr, low, left);
    return left;
}

.NET Generics は,constrained. prefix の導入で boxing を回避したりがんばってはいるのですが,でもやっぱりインライン化 (専用 IL 使用) には及ばないと.このパフォーマンスゲインが Dual Core 環境での Parallel.Do 導入によるパフォーマンスゲインより大きいってのが泣けます.やる気を出すにはコア数の多い環境を入手するところから.