由于应用中存在隐含锁,有时候应用在并行能力方面的表现可能达不到您的预期。为了保护全局访问的数据,您可能会针对同步对象明确地实施系统调用,这时便会生成隐含锁。
发现这些隐含锁的一种方法是使用“Concurrency(并发性)”分析。在您的应用上收集并发性数据,结果如下所示:

该示例显示了ShowProgress()中存在大量串行时间(请注意橙色条的相对大小)。如果我们点击突出显示的按钮来禁用“Assign system time to user calling function”特性,

Parallel Amplifier 现在显示大部分非并行时间位于 KFastSystemCallRet() 中。在右侧的“Call Stack”面板上查看堆栈数据时,我们发现该执行操作留下了我们的代码,ShowProgress(),并且输入了系统代码,即 printf()。(在下图中,系统调用呈灰色显示)。因此,调用 printf() 会生成非并行时间,进而最终导致调用 KFastSystemCallRet()。

双击“Call Stack”面板中的“ShowProgress()”将显示源代码,用户可通过该源代码调用系统代码:

在本例中,删除 printf() 调用验证了我们的结论(请注意,带有等待时间的函数列表中不再显示ShowProgress()):

并发性总结中显示并行性在增加(1.07 与 1.54):

当然,您不能总是取消系统函数调用,但是本例证明了这样一个结论:由于文件 I/O 中存在隐含锁,printf() 将导致代码的串行化。
发现这些隐含锁的一种方法是使用“Concurrency(并发性)”分析。在您的应用上收集并发性数据,结果如下所示:
该示例显示了ShowProgress()中存在大量串行时间(请注意橙色条的相对大小)。如果我们点击突出显示的按钮来禁用“Assign system time to user calling function”特性,
Parallel Amplifier 现在显示大部分非并行时间位于 KFastSystemCallRet() 中。在右侧的“Call Stack”面板上查看堆栈数据时,我们发现该执行操作留下了我们的代码,ShowProgress(),并且输入了系统代码,即 printf()。(在下图中,系统调用呈灰色显示)。因此,调用 printf() 会生成非并行时间,进而最终导致调用 KFastSystemCallRet()。
双击“Call Stack”面板中的“ShowProgress()”将显示源代码,用户可通过该源代码调用系统代码:
在本例中,删除 printf() 调用验证了我们的结论(请注意,带有等待时间的函数列表中不再显示ShowProgress()):
并发性总结中显示并行性在增加(1.07 与 1.54):
当然,您不能总是取消系统函数调用,但是本例证明了这样一个结论:由于文件 I/O 中存在隐含锁,printf() 将导致代码的串行化。
