본인의 원래 문제를이 테스트에 단순화했습니다.Parallel 내부를 일반 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는 일반적으로 약 두 배 길이에 대한 정기적으로합니다. 프로파일 러에 따르면 ParallelFor의 경우 실행 시간의 62 % -65 %가 FreeHGlobal 내부에 소비됩니다. FreeHGlobal 내부에서는 일반용으로 52 % -53 % 만 사용됩니다.
현대의 RAM 시스템에서는이 점이 너무 큰 차이를 만들지 않을 것이라고 생각했습니다. 여러 프로세스에서 많은 양의 관리되지 않는 메모리를 처리 할 수있는 방법이 있습니까? 이 스레드를 멀티 스레드로 변경하는 방법이 있습니까?
각 프로세스에 사용 된 RAM을 폐기하지 말고 테스트하기 만하면 Parallel For는 두 배 빠르지 만 그 중 약 4-5 개만 열 수 있습니다 (대량입니다). 이미지 데이터)를 응용 프로그램이 충돌하기 전과 동시에 표시합니다 (예상치 못한 것처럼 RAM 예외가 있음).
왜 개별 개체에 대해 하나 이상의 Dispose 작업을 수행하면 작업 속도가 느려 집니까?
유일한 옵션 인 경우 단일 스레드로 남겨 둘 수 있지만 속도를 높이기 위해 노력하고 있습니다.
감사합니다.
'관리되지 않는'클래스를'sealed' 클래스로 만들면'Dispose()'를 쓰는 것이'virtual Dispose (bool)'이 필요 없기 때문에 더 쉽습니다. –
AllocHGlobal()에 내장 된 잠금 장치가있어 힙을 스레드로부터 안전하게 보호합니다. 그래서 당신이 측정하고있는 것은 자물쇠가 보관되는 시간입니다. 다른 스레드가 또한 메모리를 할당하는 동안 바쁜 동안에 불가피하게 더 오래 걸립니다. –
많은 관리되지 않는 리소스 ('10 * 1024 * 1024')가 P/Invoke가 아닌 C++/CLI를 고려할 수도 있습니다. C++은 메모리 관리를위한 몇 가지 도구를 제공 할 수도 있습니다. –