线程访问各种缓冲区

Threading access to various buffers

本文关键字:缓冲区 访问 线程      更新时间:2023-10-16

我正试图找出最好的方法来做到这一点,但我有点陷入了困境,无法准确地弄清楚我要做什么,所以我要解释它是什么,我想我想做什么,以及我在哪里陷入了困境。

我正在开发一个程序,该程序有一个单独的阵列(实际上是图像(,每帧可以在图像阵列上放置大量对象。每个对象都完全独立于所有其他对象。唯一的依赖性是输出,理论上可以将其中两个对象放置在阵列的同一位置。我正在努力提高在图像上放置对象的效率,这样我就可以放置更多的对象。为了做到这一点,我想解决这个问题。

我对它进行线程处理的第一步涉及到简单的互斥保护数组。所有在数组上放置对象的操作都会调用相同的函数,所以我只需要将互斥锁放在一个位置。到目前为止,它正在发挥作用,但没有看到我希望的改善。我假设这是因为大多数时候,限制因素是图像书写声明。

我想我接下来需要做的是拥有多个正在写入的图像缓冲区,并在所有操作完成后将它们组合起来。我应该说,模糊不是问题,所需要做的只是简单地将像素数相加。然而,我正在努力弄清楚我需要使用什么机制才能做到这一点。我已经研究过信号量,但虽然我可以看到它们会限制缓冲区的数量,但我可以想象这样一种情况,即两个或多个程序将试图同时写入同一缓冲区,这可能会导致不准确。

我需要一个不涉及任何新的非标准库的解决方案。我非常愿意构建解决方案,但我非常感谢能给我一些正确的建议,因为我目前只是在黑暗中徘徊。。。

为了帮助可视化这一点,想象一下,我被告知将球放置在图像阵列的不同位置。我被告知要在每帧中放置球,并指定亮度、位置和大小。球的确切位置取决于前一帧的物理特性。所有的球都必须尽可能快地放置在最终的图像阵列上。就本例而言,如果两个球在彼此的顶部,则可以简单地将亮度相加,因此无需判断其中一个球是否挡住了另一个球。此外,不使用GPU卡;-(

Psuedo代码看起来是这样的:(假设给定了一些逻辑对象的位置、亮度和大小(。此外,假设isValidPoint只是在给定圆的位置和半径的情况下,查找该点是否应该在圆上。

global output_array[x_arrLimit*y_arrLimit)
void update_ball(int ball_num)
{
  calc_ball_location(ball_num, *location, *brightness, *size); // location, brightness, size all set inside function
  place_ball(location,brightness,size)
}
void place_ball(location,brighness,size)
{
  get_bounds(location,size,*xlims,*ylims)
  for (int x=xlims.min;x<xlims.max;y++)
  {
    for (int y=ylims.min;y<ylims.max;y++)
    {
      if (isValidPoint(location,size,x,y))
      {
        output_array(x,y)+=brightness;
      }
    }
  }
}

当前设计没有加快速度的原因是,对于整个缓冲区只有一个互斥对象,您最好不要麻烦线程处理,因为所有对象都必须串行添加(除非要进行重要的处理来确定要添加什么,但听起来并不是这样(。根据"将对象添加到缓冲区"所需的步骤(您是否使用扫描线算法、泛洪填充或其他方法(,您可能会考虑每行或一系列行有一个互斥体,或者将图像划分为每个区域有一个mutex的矩形瓦片。这将允许多个线程同时添加到图像中,只要它们不试图更新相同的区域。

好的,您在某个对象中有一个image成员。添加毫无疑问很复杂的代码来添加其他图像/对象。在可能涉及的所有其他对象中聚合,添加一些命令enun来告诉线程要执行什么操作,并在完成时调用一个"OnCompletion"事件。

将它排队到挂在生产者-消费者队列末尾的线程池中。一些线程将获取*对象,对图像/集执行操作,然后调用事件(将完成的*对象作为参数传递(。在活动中,您可以根据应用程序的需要做自己喜欢的事情。也许您会将处理后的图像添加到(线程安全!!(、向量或其他容器中,或者将它们排队到其他线程中——不管怎样。

如果必须保留处理图像的顺序(例如视频流(,您可以为提交到池中的每个对象添加一个递增的序列号,这样您的"OnComplete"处理程序就可以对"稍后"的图像进行排队,直到所有较早的图像都进入。

由于没有两个线程在同一个映像上工作,因此在处理时不需要锁定。您应该(可能(需要的唯一锁是队列内部的锁,并且它们只在向队列推送/从队列弹出对象指针所花费的时间内锁定——争用将非常罕见。