私はこのテストに私の最初の問題を単純化しました。このクラスを使用してParallel forの内部を通常のforループより遅くします。どうして?
:
public class Unmanaged : IDisposable
{
private IntPtr unmanagedResource;
public Unmanaged()
{
this.unmanagedResource = Marshal.AllocHGlobal(10 * 1024 * 1024);
}
public void DoSomethingWithThisClass()
{
Console.WriteLine($"{DateTime.Now} - {this.unmanagedResource.ToInt64()}");
}
private bool disposedValue = false; // To detect redundant calls
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
Marshal.FreeHGlobal(unmanagedResource);
disposedValue = true;
}
}
~Unmanaged() {
Dispose(false);
}
void IDisposable.Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
は、私はこれらの二つの試験があります。
public class UnitTest1
{
const int Runs = 100000;
[TestMethod]
public void UsingFor()
{
for (var i = 0; i <= Runs; i++)
{
using (var unman = new Unmanaged())
{
unman.DoSomethingWithThisClass();
}
}
}
[TestMethod]
public void UsingParallelFor()
{
Parallel.For(0, Runs, new ParallelOptions() { MaxDegreeOfParallelism = 10},
index => {
using (var unman = new Unmanaged())
{
unman.DoSomethingWithThisClass();
}
});
}
}
をParallelForは一般限りの正規の約2倍になります。プロファイラによると、実行時間の62%〜65%がParallelForのためにFreeHGlobal内部で費やされています。 FreeHGlobal内では、通常のためにわずか52%-53%が費やされています。
私は近代的なRAMシステムではこれであまり差がないと思っていました。複数のプロセスで大量の管理されていないメモリを処理する方法はありますか?これを変更してマルチスレッド化できる方法はありますか?
私が各プロセスで使用したRAMを廃棄しないでください(悪い考えでテストするだけです)、Parallel Forは2倍速いですが、その後約4〜5回しか開きません(大量ですあなたが推測したように、RAMの例外が発生している)と同時に、アプリケーションがクラッシュする前に同時に(つまり、画像データの)
別々のオブジェクトに複数のDisposeアクションを実行すると、処理が遅くなるのはなぜですか?
これが唯一のオプションであれば、私はそれらを1つのスレッドにしておくことができますが、これをスピードアップしたいと考えていました。
ありがとうございます。
'Unmanaged'を' sealed'クラスにすると、 'Dispose()'を書くのは 'virtual Dispose(bool)'の必要がないので簡単です。 –
AllocHGlobal()にはロックが組み込まれており、ヒープをスレッドセーフに保ちます。だからあなたが測定しているのは、ロックが保持されている時間です。他のスレッドもメモリを割り当てている間に必然的に時間がかかります。 –
多くの管理されていないリソース( '10 * 1024 * 1024'はそのためのプロキシになります)を扱う場合、P/InvokeではなくC++/CLIを検討するかもしれません。 C++では、メモリを管理するためのツールをいくつか追加することもできます。 –