0

我正在尝试使用 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),如果这是我可以升级它的问题,但如果这不能解决它,我不想经历麻烦。

4

2 回答 2

0

Shady 可以按原样接受uint8像素值,因此您可以删减代码以进行缩放和类型转换。当然,您会失去 Shady 以这种方式进行动态范围增强的能力,但您似乎有自己的离线解决方案来处理这种事情。如果您打算uint8专门使用刺激,您可以通过关闭抖动来节省一点 GPU 处理工作量(将和.ditheringDenominator都设置为 0 或负值)。WorldStimulus

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

请注意,您还可以通过减少Shady 必须执行LoadPages()的操作量将时间从 300-400 毫秒减少到大约 40 毫秒。numpy将数组保存为 [pages x rows x columns] 而不是 [rows x columns x pages]。相对于您现有的工作流程,这意味着您yy = yy.transpose([2, 0, 1])在保存之前执行此操作。然后,当您加载时,不要转回:只需拆分axis=0,然后squeeze是每个结果页面中最左边的维度:

pages = [ page.squeeze(0) for page in numpy.split(yy, yy.shape[0], axis=0) ]

这样,您最终将获得原始数组的 25 个视图,每个视图都是一个连续的内存块。相比之下,如果您以原始的 [行 x 列 x 页] 方式进行操作,那么无论您是进行拆分和挤压还是原始的切片和挤压循环,您都会在原始内存中获得 25 个连续视图,而这个事实迟早会追上你——如果不是当你或 Shady 在数字格式之间转换时,那么最迟当 Shady 使用 numpy 的.tostring方法序列化数据以进行传输时。

于 2019-06-21T19:28:56.077 回答
0

根据 jez 的评论、他的测试和我的测试,我猜想在某些配置上(在我的情况下是带有 Cinnamon 的 Linux Mint 19 和平庸的 AMD 显卡)加载浮点数可能比加载 uint8 慢得多。使用 uint8,行为似乎在配置之间是一致的。因此,如果可以的话,请使用 uint8。由于这将(我假设)禁用 Shady 在伽马校正和动态范围增强方面可以做的大部分事情,这可能会限制某些人。

于 2019-06-20T13:58:28.857 回答