确定隐含锁及其影响

分类:
由于应用中存在隐含锁,有时候应用在并行能力方面的表现可能达不到您的预期。为了保护全局访问的数据,您可能会针对同步对象明确地实施系统调用,这时便会生成隐含锁。

发现这些隐含锁的一种方法是使用“Concurrency(并发性)”分析。在您的应用上收集并发性数据,结果如下所示:

image1+%2528Small%2529.JPG

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

image1-3.JPG

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

image2-2.JPG

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

image3-2.JPG

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

image4-2.JPG

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

image1-4b.JPG

当然,您不能总是取消系统函数调用,但是本例证明了这样一个结论:由于文件 I/O 中存在隐含锁,printf() 将导致代码的串行化。
如需更全面地了解编译器优化,请参阅优化注意事项.