3

我正在为一个量化库构建一个原型,该库使用图像处理技术进行一些信号分析。我完全用 C# 构建了初始原型,但性能不如预期。大部分计算是通过繁重的矩阵计算完成的,这些计算占用了大部分时间。

我想知道是否值得为非托管 C++ 代码编写 C++/CLI 接口。有没有人经历过这个?欢迎提出其他优化 C# 性能的建议。

4

8 回答 8

3

曾经有一段时间用 C/C++ 编写肯定会更好,但是 C# 优化器和 JIT 现在非常好,对于纯数学来说,可能没有区别。

当您必须处理内存和可能的数组时,差异就出现了。即便如此,我仍然会使用 C#(或 F#)然后优化热点。JIT 非常擅长优化掉小的、短暂的对象。

使用数组,您必须担心 C# 对每次访问进行边界检查。读这个:

关联

自己测试一下——我一直发现 C# 具有可比性——有时更快。

于 2010-11-16T16:09:48.080 回答
3

在这里很难给出明确的答案,但如果性能是一个问题,我会找到一个经过时间考验的库,它具有您需要的性能并将其包装起来。

像乘法或除法这样简单的事情在 c++ 和 c# 之间并没有太大区别——c++ 编译器有一个优化器,而 CLR 运行时有一个按需 JITer 来进行优化。所以理论上,c++ 只会在第一次调用时胜过 c#。

然而,理论和实践并不相同。对于更复杂的算法,您还会遇到内存管理器之间的差异以及优化技术的成熟度。如果你想要轶事证据,你可以在这里找到一些数学比较重的比较

就个人而言,我发现在本地库中进行繁重的计算并使用 c++/CLI 调用它会在计算成为最大瓶颈时得到很好的提升。与往常一样,在进行任何优化之前确保是这种情况。

于 2010-11-16T16:10:30.873 回答
2

在我看来,矩阵数学最好用本机代码完成。甚至 C++ 库通常也允许绑定到LAPACK等较低级别的实现。

这里有一个 C# LAPACK 端口(在同一个站点上也是 C# BLAS),您可以尝试,但如果这比本机代码更快,我会感到惊讶。

于 2010-11-16T16:06:05.177 回答
1

我在 C# 中完成了很多图像处理工作,是的,我通常使用本机代码来处理性能很重要的重型代码,但我只使用了 PInvokes 而不是 C++/CLI 接口。不过,很多时候这不是必需的。

有很多不错的 .NET 分析器。红门一号是我个人的最爱。它可能会帮助您想象瓶颈在哪里。

于 2010-11-16T16:06:46.627 回答
1

唯一合理的语言基准:http ://shootout.alioth.debian.org/

你自己看。

于 2010-11-16T16:22:06.143 回答
0

你应该用 C++ 编写计算量大的程序,你无法通过优化 C# 来达到接近 C++ 的性能。假设计算需要相当长的时间,调用包装器的开销可以忽略不计。我已经用 C++ 和 C# 编写过代码,并且从未见过任何情况下 .NET 框架代码可以与 C++ 相媲美。在某些情况下,C# 运行得更好,但由于缺乏适当的库或 C++ 中的编码错误,它更好。如果你可以用 C# 和 C++ 编写同样好的代码,我会用 C++ 编写性能代码,其他一切都是 C#。

如果 x 是世界上最好的 C++ 程序员,而 y 是最好的 C# 程序员,那么大多数时候 x 可以编写比 y 更快的代码。但是,大多数时候 y 可以比 x 更快地完成编码。

于 2010-11-16T16:10:03.223 回答
0

C# 中的数学计算性能很差。我惊讶地发现 C# 中的数学计算有多慢。只需在 C# 和 C++ 中编写一个循环,其中包含一些乘法、Sin、Cos……,差异是巨大的。

我不知道托管 C++,但在非托管 C++ abd 中实现这一切,我想通过 P/Invoke 公开粒度接口应该不会对性能造成什么影响。

这就是我为重度实时图像处理所做的。

于 2010-11-16T16:10:43.663 回答
0

我完全用 C# 构建了初始原型,但性能不如预期。

那么你有两个选择:

用 C++ 构建另一个原型,看看它是如何比较的,或者优化你的 C# 代码。无论您使用哪种语言编写代码,在您对其进行分析和优化以及分析和优化之前,您的代码都不会很快。在 C++中尤其如此。如果您用 C# 编写可能最快的实现并将其与 C++ 中可能最快的实现进行比较,那么 C++ 版本很可能会更快。但这会以开发时间为代价。编写高效的 C++ 代码并非易事。如果您是该语言的新手,那么您很可能会编写非常低效的代码,特别是如果您来自 C# 或 Java,它们的工作方式不同,成本也不同。

如果您只是编写一个有效的实现,而不必过多担心性能,那么我猜测 C# 版本可能会更快。

但这实际上取决于您追求什么样的性能(尤其是,您需要执行的操作有多昂贵。从托管代码到本机代码的转换会产生开销,因此对于短期操作来说不值得经常执行。

C++ 中的数字运算代码可以与 Fortran 中编写的代码一样快(给或取几个百分点),但要实现这一点,您需要使用许多高级技术(表达式模板和大量元编程)或一些相当复杂的技术为您实现它的库。

这值得吗?或者 C# 是否可以足够快地满足您的需求?

于 2010-11-16T17:46:01.550 回答