Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/338.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在这种情况下,封送。复制是否占用处理器太多?_C#_Marshalling_Unmanaged - Fatal编程技术网

C# 在这种情况下,封送。复制是否占用处理器太多?

C# 在这种情况下,封送。复制是否占用处理器太多?,c#,marshalling,unmanaged,C#,Marshalling,Unmanaged,我正在研究一个实时仿真模型。模型是用非托管代码编写的,但模型是由C#托管代码控制的,称为ExecutiveManager。ExecutiveManager一次运行多个模型,并控制运行模型的计时(例如,如果一个模型的“帧速率”为每秒20,则执行人员将告诉模型何时开始下一帧) 在运行模拟时,我们看到CPU上的负载一直很高,它可以达到100%,并停留在完全合适的机器上。我使用了处理器分析器来确定问题所在,它为我指出了两种方法:WriteMemoryRegion和ReadMemoryRegion。Exe

我正在研究一个实时仿真模型。模型是用非托管代码编写的,但模型是由C#托管代码控制的,称为ExecutiveManager。ExecutiveManager一次运行多个模型,并控制运行模型的计时(例如,如果一个模型的“帧速率”为每秒20,则执行人员将告诉模型何时开始下一帧)

在运行模拟时,我们看到CPU上的负载一直很高,它可以达到100%,并停留在完全合适的机器上。我使用了处理器分析器来确定问题所在,它为我指出了两种方法:WriteMemoryRegion和ReadMemoryRegion。ExecutiveManager调用这些方法。模型具有共享内存区域,ExecutiveManager用于使用这些方法读取和写入这些区域。读和写都会打电话给Marshal.Copy,我的直觉告诉我这就是问题所在,但我不想相信我的直觉!我们将做进一步的测试来缩小范围,但我想对Marshal.Copy做一个快速的健全性检查。WriteMemoryRegion和ReadMemoryRegion在每个帧中都被调用,而且它们由ExecutiveManager中的每个模型调用,每个模型通常有6个共享区域。因此,对于10个模型,每个模型有6个区域以每秒20帧的速度运行,同时调用WriteMemoryRegion和ReadMemoryRegion,即每秒2400次Marshal.Copy调用。这是不合理的,还是我的问题在别处

 public async Task ReadMemoryRegion(MemoryRegionDefinition g) {
        if (!cache.ContainsKey(g.Name)) {
            cache.Add(g.Name, mmff.CreateOrOpen(g.Name, g.Size));
        }
        var mmf = cache[g.Name];
        using (var stream = mmf.CreateViewStream())
        using (var reader = brf.Create(stream)) {
            var buffer = reader.ReadBytes(g.Size);
            await WriteIcBuffer(g, buffer).ConfigureAwait(false);
        }
    }

private Task WriteIcBuffer(MemoryRegionDefinition g, byte[] buffer) {
        Marshal.Copy(buffer, 0, new IntPtr(g.BaseAddress), 
buffer.Length);
        return Task.FromResult(0);
    }

public async Task WriteMemoryRegion(MemoryRegionDefinition g) {
        if (!cache.ContainsKey(g.Name)) {
            if (g.Size > 0) {
                cache.Add(g.Name, mmff.CreateOrOpen(g.Name, g.Size));
            } else if (g.Size == 0){
                throw new EmptyGlobalException($@"Global {g.Name} not 
created as it does not contain any variables.");
            } else {
                throw new NegativeSizeGlobalException($@"Global {g.Name} 
not created as it has a negative size.");
            }
        }
        var mmf = cache[g.Name];
        using (var stream = mmf.CreateViewStream())
        using (var writer = bwf.Create(stream)) {
            var buffer = await ReadIcBuffer(g);
            writer.Write(buffer);
        }
    }


private Task<byte[]> ReadIcBuffer(MemoryRegionDefinition g) {
        var buffer = new byte[g.Size];
        Marshal.Copy(new IntPtr(g.BaseAddress), buffer, 0, g.Size);
        return Task.FromResult(buffer);
    }
公共异步任务ReadMemoryRegion(MemoryRegionDefinition g){
如果(!cache.ContainsKey(g.Name)){
cache.Add(g.Name,mmff.CreateOrOpen(g.Name,g.Size));
}
var mmf=缓存[g.Name];
使用(var stream=mmf.CreateViewStream())
使用(var reader=brf.Create(stream)){
var buffer=reader.ReadBytes(g.Size);
等待写入缓冲区(g,缓冲区)。配置等待(false);
}
}
专用任务WriteIcBuffer(MemoryRegionDefinition g,字节[]缓冲区){
封送处理副本(缓冲区,0,新IntPtr(g.BaseAddress),
缓冲区长度);
返回Task.FromResult(0);
}
公共异步任务WriteMemoryRegion(MemoryRegionDefinition g){
如果(!cache.ContainsKey(g.Name)){
如果(g.Size>0){
cache.Add(g.Name,mmff.CreateOrOpen(g.Name,g.Size));
}否则,如果(g.Size==0){
抛出新的EmptyGlobalException($@“Global{g.Name}不是
创建为不包含任何变量。”);
}否则{
抛出新的NegativeSizeGlobalException($@“Global{g.Name}
未创建,因为它的大小为负数。“);
}
}
var mmf=缓存[g.Name];
使用(var stream=mmf.CreateViewStream())
使用(var writer=bwf.Create(stream)){
var buffer=等待读取缓冲区(g);
writer.Write(缓冲区);
}
}
专用任务ReadIcBuffer(MemoryRegionDefinition g){
var buffer=新字节[g.Size];
Marshal.Copy(新的IntPtr(g.BaseAddress),缓冲区,0,g.Size);
返回Task.FromResult(缓冲区);
}

我需要想出一个解决方案,这样我的处理器就不会着火。我对这方面很熟悉,所以欢迎大家提出意见。再说一次,我不确定元帅。复制是个问题,但这似乎是可能的。如果您发现其他可能导致处理器问题的问题,请告诉我。

为什么使用
async/await
?这是不必要的开销。这里没有异步。完全同意@Suiden。这个项目的一个程序员经常这样做。将删除。为什么使用
async/await
?这是不必要的开销。这里没有异步。完全同意@Suiden。这个项目的一个程序员经常这样做。将删除。