我有一个非托管方法,在执行时需要占用很高的CPU。可以肯定地说,非托管调用自然占用高CPU吗?
代码如下:
public void ReadAt(long ulOffset, IntPtr pv, int cb, out UIntPtr pcbRead)
{
Marshal.Copy(buffer, 0, pv, bytesRead);
pcbRead = new UIntPtr((uint)bytesRead);
bytesRead = 0;
if (streamClosed)
buffer = null;
} 发布于 2011-01-19 01:05:03
不,概括这一点是不安全的。托管和非托管方法都使用它们执行代码所需的任何CPU。
当有人说非托管调用可能很昂贵时,他们通常指的是在托管和非托管之间切换的开销。只有当您在紧密循环中进行非托管调用时,这一特定成本才会很重要,例如在大图像上进行单像素处理。
通过适当的属性可以消除非托管调用的一些开销,特别是可以将安全检查从每次调用移动到程序集加载时。当然,对于.NET框架中的所有非托管函数,都已经这样做了。
关于为什么你在这个函数上花费了这么多时间,最好的猜测(没有更多的上下文)是你要么(a)复制了一个非常大的数组,要么(b)你经常在循环中调用这个方法。
在第一种情况下,在Marshal.Copy的托管和非托管之间切换的开销可以忽略不计,复制大的内存块将始终使CPU饱和(即,一个核心的100%使用率)。除了完全消除复制操作之外,您什么也做不了(这可能是可能的,也可能是不可能的,这取决于您如何使用缓冲区)。
如果您处于第二种情况,并且数组非常小,则可能值得切换到纯托管循环。但是不要在没有测量的情况下这样做,很容易猜错,而且Marshal.Copy的非托管实现可以比托管JIT使用更多的技巧来弥补开销。
PS:你可能想要阅读this -高CPU使用率本身并不是坏事,计算机只是试图尽可能快地完成工作。托管或非托管无关紧要,如果您的使用率低于100% (每个内核),这只意味着您的计算机无事可做。
https://stackoverflow.com/questions/4524532
复制相似问题