多线程光线跟踪上的视觉伪像

时间:2018-06-20 22:15:29

标签: c++ multithreading raytracing

我一直在尝试将RayTracer从单线程版本移植到多线程版本。在大多数情况下,它可以按预期工作,但是在两个测试用例中,会出现问题。在其中一个区域中,有一个大三角形覆盖了大部分屏幕,在某些情况下,其颜色蓝色变成了黑色

在其他情况下,问题总是会发生。以蓝色平面为背景的图像应平滑。但是,这是在MT执行中发生的情况:https://postimg.cc/image/erm55m6ff/

如果我告诉我的程序打印一些调试信息,则会产生以下结果:

  

BOTO x:403 y 405 thread_id:1

     

BOTO x:403 y 405 thread_id:1

     

BOTO x:403 y 405 thread_id:1

     

BOTO x:403 y 405 thread_id:1

换句话说,由于某种未知原因,它在单个像素上运行光线跟踪过程四次。并非所有像素都不都是恒定像素,这不会发生。当我再次运行时,打印的信息将显示一个

  

BOTO x:403 y 405 thread_id:1

行,但是其他像素会发生这种情况。换句话说,它是可变的并且可以在视觉上注意到。

这是第三次在这里打开话题进行讨论。我收到了很多建议,我一直在关注。通过这些,我意识到这不是算法问题,因为我尝试了两种不同的算法。一个将屏幕分成两半,另一个将每个线程分配给一个不同的像素(即线程0->像素0,线程1->像素1,线程0->像素2,线程1->像素3等)。两种算法都出现了伪像,尽管它们之间的差别很小(分割屏幕在屏幕顶部产生的伪像较少,如我之前发布的链接所示)。

我遵循了每次只允许一个线程渲染的建议。使用这两种算法执行了测试,并且两者都没有工件。

建议使用完全独立的数据副本。实际上,原始版本使用的是对象RayTracer的单个实例,但是该实例被发送到每个线程,并在其中执行射线跟踪子例程。因此,它为每个不同的线程创建了所有需要的数据,但是只有一个内存池,用于写入像素颜色。因此,在存在共享内存的情况下,再也不会发生像其他线程那样将线程写入此共享内存区域相同位置的情况。曾经这样一来,我就不必担心将这些东西用作锁,信号量或互斥量。 无论如何,我开始使用两个不同的实例,所以使用了两个不同的内存池。在光线跟踪过程中调整了几个计数器,并开始使用for循环进行文件写入,使用“ put”成员函数(先执行一次调用,先从线程0开始写入像素,然后从线程1开始写入像素)。 (使用单个内存池)“写入”成员函数。 它也不起作用。

召唤我这里是一个由MT引起的视觉伪像,它有可能意识到:

1)与所用算法的选择无关。 2)如果只有一个线程有效,则不会获得任何伪像。这可能意味着问题不在算法上。 3)它与锁无关。首先,从来没有真正进行过内存共享,因为公共内存池从来没有两个线程都访问过单个位置。

那会是什么?我记得有关非线程安全API的评论,但我只使用标准的c ++东西(iostream,字符串等)。可能是pthread错误?我正在使用较旧的OS,编译器和库(大约十岁)。我接受任何建议!

0 个答案:

没有答案