块大小的影响
在最坏的情况下,读取和写入一个块可以被视为随机读/写操作。 SSD 的主要优点是读取或写入小数据块的速度。 HDD 在执行此任务时要慢得多(可以观察到 100 倍),NAS 甚至可能比 HDD 慢得多。
所以问题的解决方案将是更大的块大小。我的系统(Core i5-4690)上的一些基准测试。
示例_1(块大小 (1,29,29)=3,4 kB):
import numpy as np
import tables #needed for blosc
import h5py as h5
import time
import h5py_cache as h5c
def original_chunk_size():
File_Name_HDF5='some_Path'
#Array=np.zeros((1,3712,3712),dtype=np.float32)
Array=np.random.rand(96,3712,3712)
f = h5.File(File_Name_HDF5, 'a',libver='latest')
f.swmr_mode = True
nodays=1
shape = 96*nodays, 3712, 3712
d = f.create_dataset('variable', shape, maxshape=(None,3712,3712),dtype='f',chunks=(1,29,29),compression=32001,compression_opts=(0, 0, 0, 0, 9, 1, 1), shuffle=False)
#Writing
t1=time.time()
for i in xrange(0,96*nodays):
d[i:i+1,:,:]=Array
f.close()
print(time.time()-t1)
#Reading
f = h5.File(File_Name_HDF5, 'a',libver='latest')
f.swmr_mode = True
d=f['variable']
for i in xrange(0,3712,29):
for j in xrange(0,3712,29):
A=np.copy(d[:,i:i+29,j:j+29])
print(time.time()-t1)
结果(写/读):
固态硬盘:38s/54s
硬盘:40s/57s
网络存储:252s/823s
在第二个示例中,我将使用 h5py_chache 因为我不想继续提供 (1,3712,3712) 块。标准 chunk-chache-size 只有 1 MB,因此必须更改它,以避免对块进行多次读/写操作。https://pypi.python.org/pypi/h5py-cache/1.0 https://pypi.python.org/pypi/h5py-cache/1.0
示例_2(块大小 (96,58,58)=1,3 MB):
import numpy as np
import tables #needed for blosc
import h5py as h5
import time
import h5py_cache as h5c
def modified_chunk_size():
File_Name_HDF5='some_Path'
Array=np.random.rand(1,3712,3712)
f = h5c.File(File_Name_HDF5, 'a',libver='latest',
chunk_cache_mem_size=6*1024**3)
f.swmr_mode = True
nodays=1
shape = 96*nodays, 3712, 3712
d = f.create_dataset('variable', shape, maxshape=(None,3712,3712),dtype='f',chunks=(96,58,58),compression=32001,compression_opts=(0, 0, 0, 0, 9, 1, 1), shuffle=False)
#Writing
t1=time.time()
for i in xrange(0,96*nodays):
d[i:i+1,:,:]=Array
f.close()
print(time.time()-t1)
#Reading
f = h5c.File(File_Name_HDF5, 'a',libver='latest', chunk_cache_mem_size=6*1024**3) #6 GB chunk chache
f.swmr_mode = True
d=f['variable']
for i in xrange(0,3712,58):
for j in xrange(0,3712,58):
A=np.copy(d[:,i:i+58,j:j+58])
print(time.time()-t1)
结果(写/读):
固态硬盘:10秒/16秒
硬盘:10秒/16秒
网络存储:13秒/20秒
通过最小化 api 调用(读取和写入更大的块)可以进一步提高读/写速度。
我也不想提她的压缩方法。 Blosc 可以实现高达 1GB/s 的吞吐量(CPU 瓶颈),gzip 速度较慢,但提供更好的压缩比。
d = f.create_dataset('variable', shape, maxshape=(None,3712,3712),dtype='f',chunks=(96,58,58),compression='gzip', compression_opts=3)
20秒/30秒文件大小:101 MB
d = f.create_dataset('变量', shape, maxshape=(无,3712,3712),dtype='f',块=(96,58,58),压缩='gzip',compression_opts=6)
50秒/58秒文件大小:87 MB
d = f.create_dataset('变量', shape, maxshape=(无,3712,3712),dtype='f',块=(96,58,58),压缩='gzip',compression_opts=9)
50秒/60秒文件大小:64 MB
现在是整个月(30 天)的基准。写法有点优化,写成(96,3712, 3712)。
def modified_chunk_size():
File_Name_HDF5='some_Path'
Array_R=np.random.rand(1,3712,3712)
Array=np.zeros((96,3712,3712),dtype=np.float32)
for j in xrange(0,96):
Array[j,:,:]=Array_R
f = h5.File(File_Name_HDF5, 'a',libver='latest')
f.swmr_mode = True
nodays=30
shape = 96, 3712, 3712
d = f.create_dataset('variable', shape, maxshape=(None,3712,3712),dtype='f',chunks=(96,58,58),compression=32001,compression_opts=(0, 0, 0, 0, 9, 1, 1), shuffle=False)
#Writing
t1=time.time()
for i in xrange(0,96*nodays,96):
d[i:i+96,:,:]=Array
d.resize((d.shape[0]+96,shape[1],shape[2]))
f.close()
print(time.time()-t1)
#Reading
f = h5.File(File_Name_HDF5, 'a',libver='latest')
f.swmr_mode = True
d=f['variable']
for i in xrange(0,3712,58):
for j in xrange(0,3712,58):
A=np.copy(d[:,i:i+58,j:j+58])
print(time.time()-t1)
133s/301s 带 blosc
432s/684s,gzip compression_opts=3
我在访问 NAS 上的数据时遇到了同样的问题。我希望这有帮助...