2

編集

私が解決しようとしている正確な問題を説明します。単純化された問題の説明が機能していませんでした。

負荷率に基づいて CPU コアにスレッドを割り当てる必要があるフレームワークを作成しています。なぜ私がこれを行っているのかという点について議論しないでください。

フレームワークが起動すると、次のハードウェアのマップが形成されます。

  1. レベル 1: プロセッサ ワークグループ。
  2. レベル 2: NUMA ノード。
  3. レベル 3: プロセッサ (ソケット)。
  4. レベル 4: コア。
  5. レベル 5: 論理プロセッサ (SMT システムにのみ適用可能)。

これをかなり複雑な 5 レベルの階層で表します。

ユーザーは、このハードウェア情報を照会できます。ユーザーは、レベル 4 まで、目的のワークグループ、目的の NUMA ノードなどを何も指定できません。階層 (つまり、ユーザーは、指定されたプロセッサの下に表示されないコアを指定するとは言いません)。

次に、ユーザーは範囲を指定します。たとえば、「任意の 1 つのワークグループ、任意の 1 つの numa ノード、および任意の 3 つの CPU を指定してください」のようにします。この場合、フレームワークは割り当てが最も低い 3 つの CPU を返す必要があります。これはフィルターと並べ替えのプロセスです。

ここでも、ユーザーは自分のフィルターを任意のレベルに指定できます。

ユーザーは単純に何も指定しないこともできます。つまり、フレームワークはハードウェア情報を返す必要がありますが、各レベルでの負荷割り当てに従ってソートされます。

ユーザーの指定に関係なく、プロセスは常にフィルターと並べ替えです。唯一の違いは、ユーザーが範囲、カウント、または何も指定しないことです。

このプロセスを開始するために、ユーザーから提供された情報に従ってフィルタリングされた生のハードウェア データを取得します。これは、各 L5 オブジェクトのオブジェクト {L1、L2、L3、L4、L5) の平坦化された列挙として返されます。

次に、次のことを行います。

IEnumerable<KeyValuePair<int, double>> wgSub;
IEnumerable<KeyValuePair<int, double>> nnSub;
IEnumerable<KeyValuePair<int, double>> cpSub;
IEnumerable<KeyValuePair<int, double>> coSub;

wgSub = (
        from n in query
        group n by n.L1.ID into g
        select new KeyValuePair<int, double>(g.Key, g.Sum(n => n.L1.Assignment))
    )
    .OrderBy(o => o.Value);

nnSub = (
        from n in query
        group n by n.L2.ID into g
        select new KeyValuePair<int, double>(g.Key, g.Sum(n => n.L2.Assignment))
    )
    .OrderBy(o => o.Value);

cpSub = (
        from n in query
        group n by n.L3.ID into g
        select new KeyValuePair<int, double>(g.Key, g.Sum(n => n.L3.Assignment))
    )
    .OrderBy(o => o.Value);

coSub = (
        from n in query
        group n by n.L4.ID into g
        select new KeyValuePair<int, double>(g.Key, g.Sum(n => n.L4.Assignment))
    )
    .OrderBy(o => o.Value);

query = (
            from n in query
            join wgj in wgSub on n.L1.ID equals wgj.Key
            join nnj in nnSub on n.L2.ID equals nnj.Key
            join cpj in cpSub on n.L3.ID equals cpj.Key
            join coj in coSub on n.L4.ID equals coj.Key
            select n
        )
        .OrderBy(o => o.L1.ID == wgSub.Key)
        .ThenBy(o => o.L2.ID == nnSub.Key)
        .ThenBy(o => o.L3.ID == cpSub.Key)
        .ThenBy(o => o.L4.ID == coSub.Key);

私が立ち往生しているのはオーダーバイです(4レベルの深さになります)。各サブクエリの ID で入力クエリを並べ替える必要があります。次の "thenby" などです。私が書いた内容は正しくありません。

ユーザーが範囲またはカウント (どちらも数量を意味します) を指定した場合は、おそらくレベルごとに Take も実装する必要があります。

4

1 に答える 1

1

あなたが何をしようとしているのかはよくわかりませんが、これらの線に沿ったものでしょうか?

query = query
   .OrderBy(n => wgSub.First(g => g.Key == n.L1.ID).Value)
   .ThenBy(n => nnSub.First(g => g.Key == n.L1.ID).Value)
   ...
于 2013-04-19T23:18:05.987 に答える