对我的应用程序进行概要分析表明,50%的运行时用在packArrays()
函数中,该函数执行数组转换,其中C ++强大地优于C#。
为了提高性能,我在unsafe
中使用packArrays
在运行时仅获得了较低的单位数百分比改进。为了消除缓存作为瓶颈,为了估计性能提升的上限,我在C ++中编写了packArrays
并计算了两种语言的差异。 C ++版本的运行速度比C#快约5倍。我决定试试C ++ / CLI。
因此,我有三个实现:
packArrays()
函数packArrays()
被包装到一个类中,但函数内部的代码与C ++版本相同packArrays()
的实现与前两个相同(字面意思)C ++ / CLI实现如下
QCppCliPackArrays.cpp
public ref class QCppCliPackArrays
{
void pack(array<bool> ^ xBoolArray, int xLen, array<int> ^% yBoolArray, int % yLen)
{
// prepare variables
pin_ptr<bool> xBoolArrayPinned = &xBoolArray[0];
bool * xBoolArray_ = xBarsAreTruePinned;
pin_ptr<bool> yBoolArrayPinned = &yBoolArray[0];
bool * yBoolArray_ = yBarsAreTruePinned;
// go
packArrays(xBoolArray_, xBarCount, yBoolArray_ , yLen);
}
};
packArraysWorker.cpp
#pragma managed(push, off)
void packArrays(bool * xArray, int xLen, bool * yArray, int & yLen)
{
... actual code that is identical across languages code ...
}
#pragma managed(pop)
QCppCliPackArrays.cpp
使用\clr
选项进行编译,packArraysWorker.cpp
使用No Common Language RunTime Support
选项进行编译。
问题:当使用C#应用程序同时运行C#和C ++ / CLI实现时,C ++ / CLI实现仍然只比C#快一点。
问题:
所有时间都在Release / x64中从命令行(而不是VS)在单个线程上进行。
修改
为了确定因互操作而造成的性能损失,我在Stopwatch
电话周围放置了QCppCliPackArrays::packArrays()
以及在chrono::high_resolution_clock
本身内放置packArrays()
。结果表明C# - &lt; - &gt; C ++ / CLI开关的成本约为。每10K呼叫5毫秒。根据结果,从托管C ++ / CLI切换到非托管C ++ / CLI,没有任何成本。
因此,可以排除互操作作为性能退化的原因。
另一方面,显而易见的是packArrays()
不是作为非托管运行的!但为什么呢?
编辑2:
我试图将packArrays()
链接为从单独的非托管C ++库导出的.lib文件。结果仍然相同。
编辑3:
实际的packArrays
就是这个
public void packArrays(bool[] xConditions, int[] xValues, int xLen, ref int[] yValuesPacked, ref int yPackedLen)
{
// alloc
yPackedLen = xConditions.trueCount();
yValuesPacked = new int [yPackedLen];
// fill
int xPackedIdx = 0;
for (int xIdx = 0; xIdx < xLen; xIdx++)
if (xConditions[xIdx] == true)
yValuesPacked[xPackedIdx++] = xValues[xIdx];
}
进入yValuesPacked
会将xValues
中的所有值放在相应的xConditions[i]
为真的位置。
现在,我正面临一个新问题 - 我有几个旨在解决这个问题的实现,所有这些实现都正常(测试)。当我运行一个基准测试时,会在数组86K项上长时间调用这些不同的实现50K次,我会在几秒钟内获得以下timinigs:
原始实现originalArray
是上面列出的代码。显然,QCsCpp *版本在基准测试中占主导地位 - 这些是使用C ++ / CLI的实现。但是,当我在原始应用程序中替换originalArray
时,多次调用packArrays
,使用QCsCpp *实现,整个应用程序运行SLOWER。有了这个结果,我真的很无能,我必须承认它真诚地粉碎了我。这怎么可能是真的?一如既往,非常感谢任何见解。