C# 程序在较慢的 PC 上运行得更快,反之亦然
Posted
技术标签:
【中文标题】C# 程序在较慢的 PC 上运行得更快,反之亦然【英文标题】:C# program works faster on slower PC and vice versa 【发布时间】:2012-03-26 14:00:32 【问题描述】:我有一个 OCR 程序,用 C#(WinForms 应用程序)编写。所以它的主要目的是裁剪、修改、比较、ocr 图像.. 不多也不少。当我在较慢的机器上运行这个程序时 - 我得到了更好的结果!
我的主机(固定PC):
Windows 7 X64 AMD64 5000+ X2 处理器 三星 HD502IJ 500GB 7200 RPM 16MB Cache SATA 硬盘 4GB DDR2 内存 9600GT GF显卡笔记本配置(benq joybook P52)
操作系统:WinXP x86 SP3 较慢的 AMD turion 64 X2 1.6Ghz 较慢的 80 GB 5400RPM SATA 驱动器 内存少 4 倍:仅 1 GB 的 DDR2 266Hz 100 倍慢的显卡:集成 ATI X1600(我认为显卡在这个测试中并不重要) 打开 8 个 chrome 标签页我什至无法上网你能猜出什么更快吗?
Win7执行时间:600-700+ms WinXP 执行。时间:450-500ms所以问题是 - 你将如何解释这种异常表现?是否可以在我的主 PC 上提高性能?
P.S.:我知道不看代码就很难说..对此感到抱歉
【问题讨论】:
您是在两台机器上运行相同的二进制文件,还是为 x64 环境重新编译? 我猜操作系统是这里最大的因素。 如何使用 Stopwatch 类测量执行时间? 使用科学来解决您的问题,而不是让互联网上的随机人猜测。获取一个 profiler,在两台机器上运行 profiler,比较 profile 运行,然后你就知道了。 我正在使用这两种方法进行测量:秒表和 getendtime -startTime =Elapsed。结果是+-相同的。现在,关于 x64 编译器。我有这个奇怪的问题 - 当我将应用程序编译为 x64 时 - 没有任何反应,所以我认为应用程序失败了,所以我使用了 x86 编译器。但是,我刚刚注意到——即使 x64 应用程序没有启动——我仍然可以在 Debug 文件夹中找到一个 *exe。由此产生的性能要好得多:高达 380 毫秒! 【参考方案1】:OCR 是重要的代码。最合乎逻辑的第一步是测量!根据两种环境中完全相同的测试数据分析性能。这应该让您了解哪些代码在“更快”的机器上花费的时间最长。
【讨论】:
【参考方案2】:没有更多信息很难说,但是如果您在固定 PC 上运行为 x64 编译的代码,您可能会看到我在客户端站点上遇到的问题。 64 位代码使用较大的数字,因此可能会更快地填满处理器缓存,这意味着您的代码运行速度较慢。以下是处理相同问题的先前回答的问题:How can compiling my application for 64-bit make it faster or better?
【讨论】:
【参考方案3】:我会说两个都配置文件(我使用 jetbrains),您可能会在速度更快的机器上找到一个出乎意料的热点。
另外我想说操作系统是一个很大的不同,也许拿一个 USB 启动迷你 XP,200-300mb 下载。并在那台好机器上运行代码。
同样可以使用 2 个虚拟机进行测试,只需创建一个使用 XP 的虚拟机和一个使用 windows 7 的虚拟机,看看在相同的硬件上是否存在差异。
【讨论】:
【参考方案4】:您的应用程序是多线程的吗?不久前我读过这篇文章,也许它不适用于您的情况,但仍然很有趣。
基本上,处理器类型与内核数量和应用程序的内存模型相结合可以说很多。
http://igoro.com/archive/volatile-keyword-in-c-memory-model-explained/
摘录:
在某些处理器上,编译器不仅必须避免对易失性读写进行某些优化,还必须使用特殊指令。在多核机器上,不同的核有不同的缓存。默认情况下,处理器可能不会费心保持这些缓存的一致性,并且可能需要特殊指令来刷新和刷新缓存。
主流 x86 和 x64 处理器实现了强大的内存模型,其中内存访问实际上是易失性的。因此,易失性字段会强制编译器避免一些高级优化,例如从循环中提升读取,否则会导致与非易失性读取相同的汇编代码。
Itanium 处理器实现了较弱的内存模型。要以 Itanium 为目标,JIT 编译器必须对易失性内存访问使用特殊指令:LD.ACQ 和 ST.REL,而不是 LD 和 ST。指令 LD.ACQ 有效地说,“刷新我的缓存,然后读取一个值”,而 ST.REL 说,“将一个值写入我的缓存,然后将缓存刷新到主内存”。另一方面,LD 和 ST 可能只是访问处理器的缓存,其他处理器不可见。
【讨论】:
以上是关于C# 程序在较慢的 PC 上运行得更快,反之亦然的主要内容,如果未能解决你的问题,请参考以下文章
OpenCV SimpleBlobDetector 速度性能