.NET编组速度 我有一个C++方法签名,看起来像: static extern void ImageProcessing( [MarshalAs(UnmanagedType.LPArray)]ushort[] inImage, [MarshalAs(UnmanagedType.LPArray)]ushort[] outImage, int inYSize, int inXSize);
我已经用计时方法包装了函数,包括内部和外部。在内部,该函数以0.24秒的速度运行。从外部看,该函数的运行速度为2.8秒,大约慢12倍。发生什么事?编组让我慢了那么多吗?如果是的话,我怎样才能避免呢?我应该使用不安全的代码和指针吗?我有点困惑额外的时间成本是从哪里来的。看看。虽然它的重点是紧凑的框架,但一般原则也适用于桌面。分析部分的相关引用如下: 托管调用不直接调用本机方法。相反,它调用一个JITted存根方法,该方法必须执行一些开销例程,例如确定GC抢占状态的调用(确定GC是否挂起,我们是否需要等待)。也有可能一些编组代码也会被jit到存根中。这一切都需要时间.NET编组速度 我有一个C++方法签名,看起来像: static extern void ImageProcessing( [MarshalAs(UnmanagedType.LPArray)]ushort[] inImage, [MarshalAs(UnmanagedType.LPArray)]ushort[] outImage, int inYSize, int inXSize);,.net,c++,performance,pinvoke,marshalling,.net,C++,Performance,Pinvoke,Marshalling,我已经用计时方法包装了函数,包括内部和外部。在内部,该函数以0.24秒的速度运行。从外部看,该函数的运行速度为2.8秒,大约慢12倍。发生什么事?编组让我慢了那么多吗?如果是的话,我怎样才能避免呢?我应该使用不安全的代码和指针吗?我有点困惑额外的时间成本是从哪里来的。看看。虽然它的重点是紧凑的框架,但一般原则也适用于桌面。分析部分的相关引用如下: 托管调用不直接调用本机方法。相反,它调用一个JITted存根方法,该方法必须执行一些开销例程,例如确定GC抢占状态的调用(确定GC是否挂起,我们是否需
编辑:同样值得一读的是-同样,CF特定,但仍然相关。还有,尽管这一个可能是特定于CF的(未在桌面上测试)。您尝试过将两个数组参数切换到IntPtr吗?当编组签名中的所有类型都是可空袭的时,PInvoke是绝对最快的。这意味着Pinvoke只需要一个memcpy来来回获取数据 在我的团队中,我们发现管理PInvoke图层最有效的方法是
与任何“这将更快”的答案一样,您需要分析这是您自己的代码库。我们是在考虑和分析了几种方法之后才得出这个解决方案的 不幸的是,答案远比这些建议简单,尽管它们确实有用。基本上,我搞砸了我的计时方式 我使用的计时代码是:
Ipp32s timer;
ippGetCpuFreqMhz(&timer);
Ipp64u globalStart = ippGetCpuClocks();
globalStart = ippGetCpuClocks() *2 - globalStart; //use this method to get rid of the overhead of getting clock ticks
//do some stuff
Ipp64u globalEnd = ippGetCpuClocks();
globalEnd = ippGetCpuClocks() *2 - globalEnd;
std::cout << "total runtime: " << ((Ipp64f)globalEnd - (Ipp64f)globalStart)/((Ipp64f)timer *1000000.0f) << " seconds" << std::endl;
并称之为:
unsafe {
fixed (ushort* inImagePtr = theInputImage.DataArray){
fixed (ushort* outImagePtr = theResult){
ImageProcessing((IntPtr)inImagePtr,//theInputImage.DataArray,
(IntPtr)outImagePtr,//theResult,
ysize,
xsize);
}
}
}
将可执行时间降至0.3秒(平均运行三次)。对我来说,速度仍然太慢,但速度提高10倍肯定是我老板可以接受的。我从中得出的结论是,我需要使用不安全的代码。我不介意,我将进行转换并运行测试,然后让您知道我的结果。
unsafe {
fixed (ushort* inImagePtr = theInputImage.DataArray){
fixed (ushort* outImagePtr = theResult){
ImageProcessing((IntPtr)inImagePtr,//theInputImage.DataArray,
(IntPtr)outImagePtr,//theResult,
ysize,
xsize);
}
}
}