【问题标题】:How to optimize my writing from RAM to disc?如何优化我从 RAM 到磁盘的写入?
【发布时间】:2018-07-31 01:58:42
【问题描述】:

我有一些 python 代码用于从 FPGA 的 RAM 中读取数据并将其写入计算机上的磁盘。代码的运行时间为 2.56 秒。我需要把它降低到 2 秒。

mem = device.getNode("udaq.readout_mem").readBlock(16384)
device.dispatch()
ram.append(mem)
ram.reverse()
memory = ram.pop() 
for j in range(16384):
    if 0 < j < 4096:
        f.write('0x%05x\t0x%08x\n' %(j, memory[j]))
    if 8192 < j < 12288:
        f.write('0x%05x\t0x%08x\n' %(j, memory[j]))

【问题讨论】:

  • 你为什么要做追加反向弹出? memory 是什么类型?这个转储程序,有明显的时间限制,是否需要在文本转换中将数据扩展 375%?
  • 在我的实际代码中,我没有按顺序执行追加、反向、弹出操作。我有一些条件(FiFo 交叉指针)要附加内存。为了清楚起见,我没有添加那部分。
  • 您是否分析了代码以确认您向我们展示的部分花费了相当多的时间?
  • 我使用timeit包来查找这段代码的时间。

标签: python memory optimization fpga ram


【解决方案1】:

你的循环效率很低。当值不在范围内时,您实际上是在毫无意义地进行迭代。而且您要花费大量时间来测试索引。

不要进行一次循环和两次测试。只需创建 2 个没有索引测试的循环(请注意,如果我们尊重您的测试,则会跳过第一个索引:

for j in range(1,4096):
    f.write('0x%05x\t0x%08x\n' %(j, memory[j]))
for j in range(8193,12288):
    f.write('0x%05x\t0x%08x\n' %(j, memory[j]))

也许更 Python 和更简洁(& 不使用 memory[j] 所以它有机会更快):

import itertools
for start,end in ((1,4096),(8193,12288)):
    sl = itertools.islice(memory,start,end)
    for j,m in enumerate(sl,start):
        f.write('0x%05x\t0x%08x\n' %(j, m))

外部循环保存了 2 个循环(所以如果有更多的偏移量,只需将它们添加到元组列表中)。 islice 对象创建了一个内存片,但没有复制。它迭代而不检查每次数组越界的索引,因此它可以更快。它还没有被搁置,但写入磁盘可能也需要很多时间。

【讨论】:

  • @eugenhu 有了另一个摆脱索引的想法
  • 我认为第二个代码示例中的枚举缺少开始参数。否则,它将使两个输出块都从 0 开始。
【解决方案2】:

Jean-François Fabre 对循环的观察非常好,但我们可以走得更远。该代码执行大约 8000 次写入操作,大小恒定,内容几乎相同。我们可以在一次操作中准备一个缓冲区来执行此操作。

# Prepare buffer with static portions
addresses = list(range(1,4096)) + list(range(8193,12288))
dataoffset = 2+5+1+2
linelength = dataoffset+8+1
buf = bytearray(b"".join(b'0x%05x\t0x%08x\n'%(j,0)
                        for j in addresses))

# Later on, fill in data
for line,address in enumerate(addresses):
    offset = linelength*line+dataoffset
    buf[offset:offset+8] = b"%08x"%memory[address]
f.write(buf)

这意味着更少的系统调用。很可能我们可以走得更远,例如将内存读取为缓冲区并使用b2a_hex 或类似的而不是每个单词的字符串格式。预先计算偏移量而不是使用枚举也可能有意义。

【讨论】:

    猜你喜欢
    • 2012-01-17
    • 2013-03-25
    • 1970-01-01
    • 2022-01-10
    • 1970-01-01
    • 2013-09-14
    • 2013-08-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多