通过引入OpenMP把原来单线程的程序改为多线程,窃以为最难得莫过于设定数据共享特征,如shared, private, firstprivate, lastprivate, threadprivate,数据是否在OpenMP的并行区域内是否被各线程所共享由此决定,新手难免设错。Thread data sharing event是Intel debugger extension为发现这类问题而新增的。
Enable Thread Data Sharing Event Detection使Intel debugger extension开始检测。按下Stop On Thread Data Sharing Event后,如事件发生,则程序暂停,如不按下该键,则程序运行结束后,在图片下部的窗口显示事件的相关信息,如线程号,代码行号等。
如OpenMP程序未发生该事件且结果正确则善,不然需加入 #pragma omp atomic 或 #pragma omp critical对该数据访问加以限制(串行化)
检测所有的数据访问会使程序运行得很慢很慢。一个解决方法是在访问可能的sharing data前设置断点,等运行到该处后,再启动thread data sharing detection, 离开可疑区域后再关闭检测。
因为OpenMP是将循环的计算多线程化,所以data sharing event一般都在某行/段代码反复发生,这会影响纠错工作,你不会希望看100000...次同一个事件。event filter 能帮你滤掉已知或暂不关心的事件。
下图显示怎样滤掉发生在某个函数中的thread data sharing事件
下图显示怎样滤掉发生在某个变量上的thread data sharing事件
当你设完后,在thread data sharing filter窗口中见它们,及其状态。
如下图所示, 我已打开事件监测和stop on event, 并设定两个filters。似乎程序运行到 nrOfSolutions ++时不该暂停,因为关于nrOfSolutions的filter应忽略该事件。不幸的是,程序暂停了, 原因是在非debug状态时debugger缺少相关信息无法激活filter。
请右击该filter,选择“Reevaluate”,debugger会激活该filter,程序将如你所愿,忽略该事件并继续运行。(Tip)或在debug状态下,程序暂停时设filter,那时filter被立即激活。
承接上个话题event filter. Transparent原意为透明的、显著的,但在计算机领域中它意为因为透明,而不被感知,意思完全相反。我开始认为event filter是把要的东西留下,象洗菜的篓子,但这个event filter却是设要被忽略的事件,奇怪的很,但转念一想,滤水器不就把胀东西留下吗?
所以event filter是用来设定你不关心的事件,data sharing event就不会暂停程序运行并显示相关信息。我认为设定关心的事件可能更有用,在洋洋晒晒的,几十万、甚至上百行代码的程序运行时,可能产生大量的data sharing events, 关掉几个远不如只看几个来得直观、简单。大家的想法如何?请反馈,以便我们在下个版本中增加这项功能。
---------------------------------------------
多个线程同时进入同一个函数也是发生data sharing event的一个可能,当它发生时,debugger的Break On Re-entrant Call功能会暂停程序运行。当前版本对Address的内容格式的描述不太清楚,通常你只需直接键入函数名。