我正在试图找出最好的方法来做到这一点,但我有点陷入困境,弄清楚我正在尝试做什么,所以我要解释它是什么,我想我想做什么,以及我被卡住的地方。
我正在开发一个具有单个数组(Image确实)的程序,每个帧可以在图像数组上放置大量对象。每个对象完全独立于所有其他对象。唯一的依赖是输出,理论上可以将这些对象中的2个放在阵列上的相同位置。我正在尝试提高将对象放置在图像上的效率,以便我可以放置更多对象。为了做到这一点,我想解决这个问题。
我迈向线程化的第一步涉及简单地互斥保护阵列。将对象放在数组上的所有操作都将调用相同的函数,因此我只需将互斥锁置于一个位置。到目前为止,它正在运作,但它没有看到我希望有的改进。我假设这是因为大部分时间,限制因素是图像写入声明。
我想我接下来需要做的是拥有我正在写入的多个图像缓冲区,并在完成所有操作时将它们组合在一起。我应该说遮蔽不是问题,所有需要做的就是简单地将像素计数加在一起。但是,我正在努力弄清楚我需要使用什么机制才能做到这一点。我已经查看了信号量,但是虽然我可以看到它们会限制一些缓冲区,但我可以想象一种情况,即两个或多个程序会同时尝试写入同一个缓冲区,这可能会导致不准确。
我需要一个不涉及任何新的非标准库的解决方案。我非常愿意建立解决方案,但我非常欣赏正确方向的一些指示,因为我现在只是在黑暗中徘徊......
为了帮助想象这一点,想象一下我被告知要在图像阵列上的不同位置放置球。我被告知每个框架放置球,具有给定的亮度,位置和大小。球的确切位置取决于前一帧的物理特性。所有的球必须尽可能快地放在最终的图像阵列上。出于该示例的目的,如果两个球彼此叠置,则可以简单地将亮度加在一起,因此不需要弄清楚是否有人阻挡另一个。此外,不使用GPU卡; - )
Psuedo-code看起来像这样:(假设给出了一些逻辑对象的位置,亮度和大小)。另外,假设,在给定所述圆的位置和半径的情况下,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;
}
}
}
}
答案 0 :(得分:4)
您没有看到当前设计的任何加速的原因是,对于整个缓冲区使用单个互斥锁,您可能也不会打扰线程,因为所有对象都必须以串行方式添加(除非正在进行重要的处理以确定要添加的内容,但听起来并非如此。根据“将对象添加到缓冲区”所需的内容(使用扫描线算法,泛洪填充或其他内容),您可能会考虑每行或一行范围内有一个互斥锁,或者将图像划分为矩形瓷砖,每个区域有一个互斥锁。这将允许多个线程同时添加到图像,只要他们不尝试更新相同的区域。
答案 1 :(得分:0)
好的,你在某个对象中有一个图像成员。添加无疑是复杂的代码来添加其他图像/对象。无论如何都要操纵它。在可能涉及的所有其他对象中聚合,添加一些命令enun来告诉线程要执行的操作以及完成时要调用的'OnCompletion'事件。
将其排队到挂在生产者 - 消费者队列末尾的线程池。某些线程将获取*对象,对图像/集执行操作,然后调用事件,(将完成的*对象作为参数传递)。在这种情况下,您可以根据应用的需要做自己喜欢的事情。也许你会将处理过的图像添加到(线程安全!!),矢量或其他容器中,或者将它们排队到其他线程 - 无论如何。
如果必须保留处理图像的顺序(例如视频流),则可以向提交到池的每个对象添加递增序列号,以便启用“OnComplete”处理程序排队后来的'图像,直到所有早期的图像进入。
由于没有两个线程在同一个图像上工作,因此处理时不需要锁定。您应该(可能)需要的唯一锁定是队列内部的锁定,并且它们只锁定推送/弹出对象指针到队列/从队列中弹出的时间 - 争用将非常罕见。