Shady上的LoadPage在Linux Mint上非常慢

时间:2019-06-19 20:29:53

标签: python shady

我正在尝试使用Shady显示一系列帧,但是遇到了麻烦。我正在看25帧,覆盖1080x1080像素的区域。刺激是灰度的,我正在离线进行亮度线性化,所以我只需要为每个像素保存一个uint8值。因此,整个序列约为29Mb。我将刺激定义为3-D numpy数组[1080x1080x25],然后使用np.save()将其保存到磁盘。然后,我使用np.load()加载它。

    try:
        yy = np.load(fname)
    except:
        print fname + ' does not exist'
        return

此步骤大约需要20毫秒。据我了解,Shady不处理uint8亮度值,而是处理0到1之间的浮点数。因此,我将其转换为一个浮点数数组并除以255。

yy = yy.astype(np.float)/255.0

第二步大约需要260毫秒,这已经不是很大了(理想情况下,我需要加载刺激并准备在400毫秒内呈现)。 现在,我创建了一个25个numpy数组的列表,用作Stimulus类中的 pages 参数:

    pages = []
    for j in range(yy.shape[2]):
        pages.append(np.squeeze(yy[:, :, j]))

这实际上是瞬时的。但是在下一步中,我遇到了严重的计时问题。

if (self.sequence is None):
    self.sequence = self.wind.Stimulus(pages, 'sequence', multipage=True, anchor=Shady.LOCATION.UPPER_LEFT, position=[deltax, deltay], visible=False)
else:
    self.sequence.LoadPages(pages, visible=False)

在这里,如果不是我加载的第一个序列,我要么创建一个Stimulus对象,要么更新其 pages 属性。无论哪种方式,此步骤大约需要10秒钟,大约是我在应用程序中可以承受的100倍。

有没有一种方法可以显着加快速度?我究竟做错了什么?我在这台机器(Radeon Pro WX 4100)上有一个非常普通的图形卡,如果那是问题,我可以对其进行升级,但是如果那不能解决它,我不想经历麻烦。

2 个答案:

答案 0 :(得分:1)

基于jez的评论,他的测试以及我的测试,我猜想在某些配置(在我的情况下,装有Cinnamon的Linux Mint 19和中等的AMD视频卡)上,加载float可能比加载uint8慢得多。使用uint8时,行为在各个配置之间似乎是一致的。因此,如果可以,请使用uint8。由于这(我认为)将使Shady在伽玛校正和动态范围增强方面无法做的很多事情,因此这可能会限制某些功能。

答案 1 :(得分:0)

Shady可以原样接受uint8个像素值,因此您可以剪切代码以进行缩放和类型转换。当然,您会失去Shady那样做动态范围增强功能的能力,但似乎您拥有针对此类情况的脱机解决方案。如果您打算仅使用uint8刺激,则可以通过关闭抖动功能(设置.ditheringDenominator和{{1}的World来节省一些GPU处理工作。 }设为0或负值。

当将原始纹理数据从RAM传输到图形卡时,似乎可笑的10到15秒的延迟来自编译的二进制“加速器”组件内部。该问题显然是(a)特定于传输浮点纹理数据而不是整数数据,并且(b)特定于您拥有的显卡(因为当您更换NVidia卡后,该问题在同一系统上消失了) )。关于旧显卡,可能也是特定于操作系统或驱动程序的。

请注意,您还可以通过减少Shady必须执行的Stimulus操作量,将LoadPages()时间从300–400ms减少到大约40ms。将数组另存为[行x列x页],而不是[行x列x页]。相对于现有工作流程,这意味着您在保存之前先进行numpy。然后,当您加载时,不要转回:分别在yy = yy.transpose([2, 0, 1])上分割,然后在每个结果页面的最左侧维度axis=0进行分割:

squeeze

这样一来,您将获得原始数组的25个视图,其中每个 是一个连续的内存块。相比之下,如果您以原始的[行x列x页]的方式进行操作,则无论您执行分割压缩还是原始的切片压缩循环,都会得到25个 non -连续的视图进入原始内存,这一事实迟早会跟上您的步伐-如果不是在您或Shady在数字格式之间进行转换时出现,则最迟在Shady使用numpy的pages = [ page.squeeze(0) for page in numpy.split(yy, yy.shape[0], axis=0) ] 方法来序列化要传输的数据时