首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在时间临界循环中确定200 ms冻结的原因

在时间临界循环中确定200 ms冻结的原因
EN

Stack Overflow用户
提问于 2014-11-12 12:48:03
回答 3查看 297关注 0票数 0

对问题的新描述:

目前,我在一个测试环境中运行我们的新数据采集软件。该软件有两条主线。其中一个包含一个快速循环,它与硬件通信,并将数据推入一个双缓冲区。每隔几秒钟,这个循环就会冻结200 ms。我做了几个测试,但没有一个让我知道软件在等待什么。由于软件相当复杂,测试环境可能也会干扰软件,所以我需要一种工具/技术来测试记录器线程在阻塞200 ms时等待什么。什么工具对实现这一点是有用的?

原始问题:

在我们的数据采集软件中,我们有两个线程提供主要功能。一个线程负责从不同的传感器收集数据,另一个线程将数据保存到大块的磁盘中。数据被收集在一个双缓冲区中。它通常每项包含100000字节,每秒收集多达300个项。一个缓冲区用于在数据收集线程中写入数据,一个缓冲区用于读取数据并将其保存到第二个线程中的磁盘中。如果已读取所有数据,则切换缓冲区。缓冲区的切换似乎是一个主要的性能问题。每次缓冲区切换时,数据收集线程阻塞大约200 ms,这太长了。然而,偶尔也会发生这样的情况,即切换速度快得多,几乎不需要时间。(测试PC: Windows 7 64位,i5-4570 CPU @3.2 GHz (4核),16 GB DDR3 (800 MHz))。

我的猜测是,性能问题与在核之间交换的数据有关。只有当线程偶然地在同一个核心上运行时,交换才会更快。我考虑将线程关联掩码设置为强制两个线程在同一个内核上运行的方式,但这也意味着我失去了真正的并行性。另一个想法是让缓冲区在切换前收集更多的数据,但这大大降低了数据显示的更新频率,因为它必须等待缓冲区切换才能访问新数据。

我的问题是:是否有一种技术可以将数据从一个线程移动到另一个线程,而不干扰收集线程?

编辑:双缓冲区实现为两个std::向量,用作环缓冲区。bool (int)变量用于判断哪个缓冲区是活动的写缓冲区。每次访问双缓冲区时,都会检查bool值,以确定应该使用哪个向量。切换双缓冲区中的缓冲区只意味着切换这个bool值。当然,在切换过程中,所有的读和写都会被互斥阻塞。我不认为这个互斥可能会阻塞200毫秒。顺便说一句,200毫秒对于每个开关事件都是非常可复制的。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2014-11-20 14:03:50

在讨论了聊天中的问题后,发现Windows Performance是一个适合使用的工具。该软件是Windows的一部分,可以在命令窗口中使用命令wprui打开。(Alois在聊天中发布了这个有用的链接:http://geekswithblogs.net/akraus1/archive/2014/04/30/156156.aspx )。以下步骤揭示了该软件一直在等待的内容:

  • 使用默认设置用WPR记录信息,并在WPA中加载保存的文件。
  • 标识相关线程。在这种情况下,记录线程和保存线程显然具有最高的CPU负载。可以很容易地识别保存线程。由于它将数据保存到磁盘,所以它是具有文件访问权限的。(看看记忆->硬性错误)
  • 查看计算->CPU使用(精确),并选择利用按进程,线程。选择正在分析的过程。最好按顺序显示列: NewProcess,ReadyingProcess,ReadyingThreadId,NewThreadID,黄条,就绪(S)和,等待(S)和,计数.
  • 在ReadyingProcess下,我寻找具有最大等待时间(S)的流程,因为我期望这个过程负责延迟。
  • 在ReadyingThreadID下,我检查了每一行,其中引用了NewThreadId列中的延迟线程。经过一次简短的搜索,我发现了一条显示频繁等待约100毫秒的帖子,它总是以一对的形式出现。在列ReadyingThreadID中,我能够读取记录循环等待的线程的id。
  • 根据它的CPU使用情况,这个线程基本上什么也不做。在我们的特殊情况下,这导致我假设串行端口io命令可能导致此等待。在使他们失去活力之后,延迟就消失了。重要的发现是,200毫秒的延迟实际上是由两个100毫秒的延迟组成的。

进一步的分析表明,通过虚拟串口对获取数据的命令有时会丢失。这可能与数据保存和压缩循环中非常高的CPU负载相关联。如果fetch命令丢失,则不接收数据,第一次和第二次尝试接收数据的超时时间为100毫秒。

票数 0
EN

Stack Overflow用户

发布于 2014-11-13 20:31:54

锁定和释放互斥物,仅仅为了切换一个bool变量,将不会花费200 to。

主要问题可能是两个线程在某种程度上相互阻塞。这种阻塞称为锁争用。基本上,每当一个进程或线程试图获取另一个进程或线程持有的锁时,就会发生这种情况。相反,并行您有两个线程在等待对方完成他们的部分工作,具有类似于单线程方法的效果。

为了进一步阅读,我推荐阅读文章,该文章更详细地描述了锁争用。

票数 2
EN

Stack Overflow用户

发布于 2014-11-20 13:18:42

既然您是在windows上运行,那么您可能使用visual studio吗?如果是的话,我会求助于VS分析器,在这种情况下非常好(IMHO),一旦您不需要检查数据/指令缓存(那么英特尔的vTune是一个自然的选择)。根据我的经验,VS足够好地捕捉争用问题以及CPU瓶颈。您可以直接从VS或作为独立工具运行它。您不需要在测试机器上安装VS,您只需复制该工具并在本地运行。

VSPerfCmd.exe /start:SAMPLE /attach:12345 /output:samples -附加到进程12345并收集CPU采样信息

VSPerfCmd.exe /detach:12345 -与过程分离

VSPerfCmd.exe /shutdown -关闭分析器,编写samples.vsp (参见第一行)

然后您可以打开该文件并在visual studio中检查它。如果您没有看到任何东西使您的CPU忙切换到争用分析-只需将“开始”参数从“示例”改为“并发性”。

该工具位于%YourVSInstallDir%\ Tools\Performance \下面,可以从VS2010获得

祝好运

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26887403

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档