2ミリ秒で50の戦略を実行する必要がありstrategy.AllTablesUpdated();
ます(そして、1秒間に約500回繰り返す必要があります)。以下のコードを使用して、Monitor.TryEnter
呼び出しに最大1ミリ秒(!!!)かかることがわかりました。これを50回行います。
// must be called ~500 times per second
public void FinishUpdatingTables()
{
foreach (Strategy strategy in strategies) // about ~50, should be executed in 2 ms
{
// this slow and can be paralleled
strategy.AllTablesUpdated();
}
}
...................。
public override bool AllTablesUpdated(Stopwatch sw)
{
this.sw = sw;
Checkpoint(this + " TryEnter attempt ");
if (Monitor.TryEnter(desiredOrdersBuy))
{
Checkpoint(this + " TryEnter success ");
try
{
OnAllTablesUpdated();
} finally
{
Monitor.Exit(desiredOrdersBuy);
}
return true;
} else
{
Checkpoint(this + " TryEnter failed ");
}
return false;
}
public void Checkpoint(string message)
{
if (sw == null)
{
return;
}
long time = sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L));
Log.Push(LogItemType.Debug, message + time);
}
ログ(µs単位)から、失敗した試行には約1ミリ秒かかります。
12:55:43:778デバッグ:TryEnterの試行1264 12:55:43:779デバッグ:TryEnterが失敗しました2123
ログ(µs単位)から、成功の試行には約0.01msが費やされます。
12:55:49:701デバッグ:TryEnterの試行889 12:55:49:701デバッグ:TryEnterの成功900
Monitor.TryEnter
だから今、それは私が50の戦略のために一つずつ実行するには高すぎると思います。だから私はこのようなものを使ってこの仕事を並行させたいと思いTask
ます:
// must be called ~500 times per second
public void FinishUpdatingTables()
{
foreach (Strategy strategy in strategies) // about ~50, should be executed in 2 ms
{
// this slow and can be paralleled
Task.Factory.StartNew(() => {
strategy.AllTablesUpdated();
});
}
}
Monitor.TryEnter
また、そのようなアプローチと同じlock
ように、すべてが非同期になるように置き換えることもできます。
私の質問:
- なぜ
Monitor.TryEnter
そんなに遅いのですか?(ロックが取得されていない場合は1ミリ秒) - 2ミリ秒ごとに50を開始するのはどれくらい良いでしょうか
Task
=毎秒25000のタスク?.NETはこれを効果的に管理できますか?また、生産者/消費者パターンを使用してBlockingCollection
、50人の「労働者」を1回だけ開始し、2ミリ秒ごとに50個のアイテムの新しいパックをBlockingCollectionに送信することもできますか?それは良いでしょうか? - 2ミリ秒ごとに並列化できる50のメソッド(1秒あたり500回)をどのように実行しますか?合計で1秒あたり25000回ですか?