对托管C ++ VS非托管/本机C ++的性能

我写了处理和处理数百个事件的每一毫秒一个非常高的性能应用。

是非托管C ++快于托管C ++? 为什么?

管理与CLR,而不是操作系统和CLR C ++的交易负责内存管理,从而简化代码,很可能也比托管C写的“程序员”的代码更有效++? 还是有其他原因? 当使用管理,怎么能那么可以避免动态内存分配,这会导致性能损失,如果是全透明的程序员和CLR处理?

所以回来我的问题,是管理C ++在速度上比非托管C ++,为什么方面更有效率?

--------------解决方案-------------

没有一个答案。 作为一个真正的一般规则 ,本地代码通常会更快,但1)这并非总是如此,2)有时差别太小,关心,和3)如何被编写的代码通常会做出比管理更差与非托管。

编辑:托管代码在虚拟机上运行。 基本上,在启动与产生字节代码作为输出一个编译器,然后反馈该给虚拟机。 虚拟机然后可以将其解释或重新编译到机器代码并执行。 无论哪种方式,你已经增加了一些开销。

虚拟机还采用了垃圾收集器。 垃圾收集器已经从手工管理内存,而不同的特点。 凭借最原始的手工管理,分配内存是相当昂贵的。 释放内存是相当便宜,但大致线性你释放的项数。

随着垃圾回收,分配内存通常是很便宜的。 与典型的(复印)集电极,释放存储器的成本主要取决于已分配和仍然(至少可能)使用的对象的数目。

该分配本身也各不相同,但。 在本地C ++,你通常创建堆栈,其中两个分配和释放内存非常便宜的大多数对象。 在托管代码,您通常动态分配的内存更大的比例,它的垃圾收集。

您可以编写代码的速度慢,在任何语言; 相反,你可以用体面的算法,很可能是快是几乎所有的语言。

常见的答案在这里是来接你已经知道,使用适当的算法语言,然后配置文件的挫折感出它来确定实际的热点。

我有些担心的数百个事件每毫秒声明 。 这是一个可怕的很多。 你有理由要能做到在任何语言期望处理?

作为一个C ++的高性能系统开发人员,我倾向于相信我的能力来分析和优化发出的代码。 这就是说, 也有极高性能的.NET应用程序,在这里笔者已经竭尽全力不做动态内存分配的临界循环内 - 主要是通过使用预先创建的对象的分配池。

因此,要重复我以前的评论:挑选你已经知道,然后调。 即使你进入了死胡同; 你可能会知道更多关于你的问题的空间。

这一切都取决于具体情况。

事情让非托管代码更快/托管代码慢:

  • 需要代码转换为机器代码可以执行前
  • 垃圾回收可能会导致开销
  • 从托管到非托管代码有一个严重的开销调用
  • 非托管的编译器可以优化更多,因为他们直接生成机器码(看到我)

事情让托管代码更快/非托管代码慢:

  • 因为代码转换成机器代码它的使用权之前,托管代码可以为处理器的实际进行优化(与非托管代码,你必须针对“最低支持”处理器)。

而且可能还有更多的原因。

写快速的代码,是永远的痛。 主要的问题,您可以优化只是一个平台。 这实在是对控制台的情况下,嵌入式或其他平台,硬件始终是相同的。 在现实世界PC心不是这样的情况。 不同的核心,不同的istruction ECC ......使这是一个噩梦。 这是主要的问题,恕我直言,这真的让男人/墨西哥国立自治大学的代码之间的区别。 人。 代码可以乐观优化的新平台时,它的运行。 令人愁闷代码不,被写入到石头。

托管代码是在大多数情况下比非托管代码要慢,尽管.NET CLR总是做了JIT编译执行代码(在程序运行时就不会被编译多次,但它也从来没有解释的代码)之前。

现在的问题是相当有许多检查CLR呢,比如就看你跑过来一个数组的边界,只要你尝试访问它。 这导致带缓冲器溢出等问题较少,但也意味着一个性能命中由于这些检查的额外开销。

我见过的实验,其中C#优于C ++,但那些进行了代码为服用对象层次结构等大量优势当涉及到数字运算,并要充分利用你的电脑,你将不得不去与非托管代码。

另一点也已经提到 - 气相色谱会导致一定程度时,内存必须释放在程序执行的不可预知的暂停。 你需要这个时间,以及在非托管代码执行内存管理的时候,但更多的时候发生,每当你决定要消灭的对象,这意味着它不是全部一次完成整个程序,所以你不要有长时间的停顿。

有很多很好的答案,但托管代码的一个方面,可能会给它在长期的优势是运行时分析。 由于由管理编译器生成的代码是一种中间格式,实际执行的机器代码可以根据实际使用情况进行优化。 如果频繁使用的功能的特定子集,所述JIT'er可以本地化机器代码都在同一存储器页,增加局部性。 如果特定子呼叫被从一个特定的方法重复进行,一个JIT'er可以动态内联它。

这是一种改进非托管代码,其中内联必须“猜测”时间提前,而且过多的内联是有害的,因为它涨大的代码大小和原因导致(非常非常耗时)L2 / L1高速缓存未命中局部性问题。 这些信息是根本无法使用静态分析,所以它只能在一个JIT'ing环境。 有一个好吃的东西篮子从运行时分析可能​​的胜利,如优化的循环展开,等等。

我不是说了.NET JIT'er是一样聪明,因为它可能是,但我知道,我听说过全球分析的功能,我知道了很多研究,运行时分析已经完成,在惠普等公司。

首先,你的声明“处理数百个事件的每一毫秒。” 听起来很不切实际。 除非你有在计算机中的特殊设计的时钟模块,我不不认为你可以实现一个通用PC的目标(典型的分辨率大约是10毫秒)。 其次,本机C ++是在性能方面巨大的更好。 有很多的优化可以采取在C ++中的术语加快,而在托管代码,他们是不可能的。 另外要注意,在托管代码的垃圾收集,使性能不可预知的 - 当GC触发了整个过程被冻结。 一旦你碰到问题,解决的办法是比较痛苦的,现在所有的“好风”由托管代码提供将不复存在。

至于用于管理代码可优化CPU的能力,这是事实,但你可以利用CPU的功能(SSE2,MMX等)的本地C ++了。 根据我的经验,性能提升可以忽略不计。

这里有一些方法,托管代码可以在性能非托管代码:

JIT编译器可以检测到该应用程序在Pentium 4上运行,并产生本机代码利用了由Pentium 4处理器通常提供的任何特殊说明,不受管理的应用程序被编译为最小公分母CPU,并避免使用特殊指令会为应用程序在更新CPU的性能提升。

JIT编译器可以检测到某个测试始终是假的当前主机上。 例如,对于像这样的码的方法:

if (numberOfCPUs > 1) {
...
}

可能导致JIT编译器不生成用于上述代码任何CPU指令如果主机具有仅1个CPU。 在这种情况下,本机代码已经被微调为主机:代码较小,执行速度更快。

在CLR可以分析代码执行和重新编译IL到本地代码的应用程序运行时。 重新编译代码可以进行重组,以减少不正确分支预测根据观察到的执行模式。

对于这些和许多其他原因,你应该会使用托管代码的未来成就要执行比今天的非托管代码更好。 正如我所说,今天的表现是大多数应用相当不错,并承诺改善随着时间的推移。

是不是C ++ / CLI像Java半解释语言?

此外,也没有一个人发表的研究只是昨天表明,气相色谱系统总是比非GC慢?

分类:C# 时间:2015-03-14 人气:0
分享到:

相关文章

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.446 (s). 10 q(s)