[英]How to optimize my writing from RAM to disc?
I have some python code for reading data from RAM of an FPGA and writing it to disk on my computer. 我有一些python代码,用于从FPGA的RAM读取数据并将其写入计算机上的磁盘。 The code's runtime is 2.56sec.
该代码的运行时间为2.56秒。 I need to bring it down to 2sec.
我需要将其降低到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]))
Your loop is very unefficient. 您的循环效率很低。 You're literally iterating for nothing when values aren't in range.
当值不在范围内时,您实际上是在不进行任何迭代。 And you're spending a lot of time testing the indices.
而且您要花费大量时间来测试索引。
Don't do one loop & 2 tests. 不要做一次循环和2次测试。 Just create 2 loops without index tests (note that first index is skipped if we respect your tests:
只需创建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]))
maybe more pythonic & more concise (& not using memory[j]
so it has a chance to be faster): 也许更pythonic&更简洁(&&不使用
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))
the outer loop saves the 2 loops (so if there are more offsets, just add them in the tuple list). 外循环保存2个循环(因此,如果有更多偏移量,只需将它们添加到元组列表中)。 The
islice
object creates a slice of the memory but no copies are made. islice
对象创建内存的一部分,但不进行任何复制。 It iterates without checking the indices each time for array out of bounds, so it can be faster. 每次迭代时都无需检查索引是否超出数组范围,因此可以更快。 It has yet to be benched, but the writing to disk is probably taking a lot of time as well.
它尚未进行试验,但是写入磁盘可能也要花费很多时间。
Jean-François Fabre's observations on the loops are very good, but we can go further. 让·弗朗索瓦·法布尔(Jean-FrançoisFabre)对循环的观察非常好,但是我们可以走得更远。 The code is performing around 8000 write operations, of constant size, and with nearly the same content.
该代码正在执行大约8000次写操作,这些写操作的大小恒定,内容几乎相同。 We can prepare a buffer to do that in one operation.
我们可以准备一个缓冲区来完成一个操作。
# 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)
This means far fewer system calls. 这意味着更少的系统调用。 It's likely we can go even further by eg reading the memory as a buffer and using
b2a_hex
or similar rather than a string formatting per word. 通过读取内存作为缓冲区并使用
b2a_hex
或类似内容而不是每个单词使用字符串格式,我们可能会走得更远。 It might also make sense to precalculate the offsets rather than using enumerate. 预先计算偏移量而不是使用枚举可能也很有意义。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.