1

我有一个 Delphi 7 32 位应用程序。视窗 7 64 位。

一切运行良好。我最近一直在调查我注意到的性能问题。

应用程序的简要概述 -->

有一个命令行/控制台应用程序可执行文件,用 Delphi 编写。这将创建一组多线程连接并执行数据库工作。一个 NT 服务,用 Delphi 编写(调用命令行应用程序),基于它找到的作业计划。这是通过调用我们的 DLL 来完成的,它为命令行应用程序查找并执行 CreateProcess,并为其完成 WaitForSingleObject。实际上,该服务负责查找何时需要完成工作,并调用可执行/控制台应用程序来完成它。

这是我的问题,我似乎无法弄清楚。

如果我运行命令行应用程序,我得到的结果大约比 NT 服务通过 CreateProcess 调用它快 4 倍。这是相同的代码。一种是在 DOS 提示符下发布 EXE,另一种是 NT 服务,它加载一个 DLL,然后为同一个可执行文件调用 CreateProcess。

我要去香蕉。我看不出有任何理由。

到目前为止,我可以在任何系统配置上重现这一点。

到目前为止我注意到的(不科学,但肯定与 imo 相关)。

如果我用 CPU 时间和内核时间监控 CPU 内核,控制台应用程序在其执行的生命周期内只有一小部分内核时间。当调度程序服务运行它时,内核时间代表我得到的任何 CPU % 使用的 50-70%% 或更多。

一些实际结果(我相信其他一切实际上都无关紧要) - 控制台应用程序,通过命令行运行:26 秒 - 控制台应用程序,通过 CreateProcess 运行服务:113 秒

是什么赋予了?

我已经调查过 FastMM 可能没有被正确共享。我相信是的。我什至删除了它。同样的异常。我已经研究过 FastCode,FastMove 的东西在服务下可能不起作用(因为在启动时,它试图动态挂钩/替换核心 RTL 函数。从等式中删除它们,同样的异常。我已经考虑删除我们修补的 RTL (System.dcu/SysInit.dcu) 文件。没有乐趣。

一切都无济于事。

所以,我的问题(以及可能的原因征求)是......

NT 服务是否排除了执行自动化/挂钩替换功能的能力?Delphi 服务是否创建了会导致这种情况的东西?服务是否存在某种固有的开销——(而且数量巨大)?是否有其他人因为这种性质而使用的 FastMM、FastCode、FastMove 的替代方法?

在此先感谢您的任何指导/帮助。

这是用于从 NT 服务启动应用程序的代码片段。

FillChar(si, SizeOf(si), 0);
si.dwFlags := SW_HIDE;
FillChar(pi, SizeOf(pi), 0);

sCommandLine := Format('"%s" "%d"', [ExtractFilePath(ParamStr(0)) + 'MYAPP.EXE', AJobID]);

If CreateProcess(PChar(sFilename),
    PChar(sCommandLine),
    Nil,
    Nil,
    False,
    0,
    Nil,
    Nil,
    si,
    pi) Then Begin

    WaitForSingleObject(pi.hProcess, INFINITE);
    GetExitCodeProcess(pi.hProcess, ExitCode);
    Result := (ExitCode = 0);

End Else Begin

    AddEventLogMessage(SysErrorMessage(GetLastError));

End;
4

1 回答 1

1

事实证明,该问题与连接的使用和共享连接有关。

一旦我采取了在启动 CreateProcess 之前破坏调度程序上的连接的方法,内核使用情况又回到了我直接从控制台运行时看到的内容。

非常令人惊讶,因为该连接甚至没有与命令行正在执行的操作共享。

未来参考:在说这两种方法相同之前,一定要消除所有变量。在这方面,他们不是。调度程序有连接,控制台应用程序没有。这就是所有的区别。

于 2013-02-07T04:38:54.437 回答