我目前正在将 VS2005 C++ 应用程序从 CE5 移植到 CE6,并且遇到了严重的性能问题。到目前为止,检索动态内容的单个 HTTP 请求在 CE5 上需要 40 毫秒,在 CE6 上需要 350 毫秒。由于我已经清理了一堆低效率,提高了两个系统的性能,这些值过去更糟,但目前我被困在那个延迟上。作为记录,这两项测试都是在同一台机器上进行的,并且网络服务器不是 CE 提供的服务器,而是用 C++ 实现的自定义服务器。另请注意,问题不在于网络 IO,CE6 在提供静态文件时甚至在同一台机器上的性能优于 CE5,而在于动态内容处理。
在试图弄清楚为什么程序执行如此糟糕的过程中,我偶然发现了一些让我感到困惑的事情:在 CE5 下,用于 x86 的 Interlocked* API 既不使用编译器内在函数,也不使用真正的函数调用,而是使用内联汇编代码。这段代码有一条注释说,内在函数包含仅多处理器系统需要的锁定前缀,并且会减慢仅在 CE5 等单核上运行的代码。在 CE6 上,这些函数是使用编译器内部函数(包括锁定前缀)实现的。由于这些函数被 Boost 和 STLport 等使用,它们都在网络服务器内部使用,我想知道这些函数是否是罪魁祸首。
我注意到的另一件事是一些字符串解析函数需要很长时间。更糟糕的是,似乎在第一次之后第二次调用相同的函数花费的时间更少,所以看起来好像正在进行某种缓存。由于这是一个通过 TCP 接收并在内存中解析的短字符串(<1kB),我无法想象哪个缓存可能对此负责。唯一的缓存可能是指令缓存,但程序不大于 CE5 版本,如果代码从未缓存的内存中运行,则不会显示这些缓存效果。
TLDR - 问题:
- CE6 是否能够处理多个处理器?
- 有没有一种简单的方法可以告诉编译器它应该省略锁定前缀?我目前实现这一目标的方法是简单地从 CE5 SDK 复制内联程序集,但这太难看了。
- 我也很感激任何其他建议看什么或尝试什么。提前谢谢了!
总结依赖可执行文件没有问题,更不用说Interlocked API了。运行相同的可执行文件证明了这一点。但是,在具有不同平台设置的不同机器上运行会有所不同。我们现在回到 Platform Builder,试图找出两个平台之间的差异。