使用ibs / obs的dd速度问题

时间:2011-06-27 02:29:59

标签: perl command-line dd

我有一个循环,我使用dd将流复制到磁盘。由于速度原因,我在整个过程中使用'bs'来使用更大的块大小。但是对于一个特定的行,我必须使用'ibs'和'obs',因为我的'seek'位置不是我在别处使用的'bs'的倍数。

我的问题是:有没有办法使用dd或任何其他程序/ Perl模块写出与用于“搜索”的块大小不同的块大小?

dd if=/dev/ram1 of=/dev/sdb1 seek=2469396480 ibs=1048576 obs=1 count=1

正如您在上面所看到的,当原始数据在1M块中读取时,我必须以1字节段写出它,因为我需要根据字节粒度寻找特定位置。这使得写入速度提高了1/100。

有解决方法吗?或者有没有办法在不使用dd的情况下在Perl中执行此操作?

谢谢,

尼克

1 个答案:

答案 0 :(得分:0)

此问题是dd中固有的。如果你想要的搜索位置没有合适幅度的因子(大到足以获得良好的性能但足够小以用作缓冲区大小)那么你就会被卡住。当你想要的寻找位置是一个大的素数时,这种情况会发生。

在这种特定情况下,正如Mark Mann指出的那样,你有很好的选择:2469396480是2355块大小为1048576,或1024块大小为2411520等...但是这不是一般答案。

要做到这一点,您需要使用dd以外的其他内容。幸运的是,dd的任务非常简单,你只需要以下内容(伪代码......我暂时没有做太多Perl)

if = open("/dev/ram1", "r")
of = open("/dev/sdb1", "r+")
seek(of, 2469396480)
loop until you have copied the amount of data you want {
    chunk = read(if, min(chunksize, remaining_bytes_to_copy))
    write(of, chunk)
}

看起来您的副本的来源是某种ramdisk。如果您真的想要尖叫性能,除了将块读取到缓冲区并将缓冲区写入输出文件之外,您可以尝试另一种方法。例如,您可以直接从映射地址mmap()源文件和write()。 OS可以(或可以不)优化RAM到RAM复制操作之一。请注意,此类方法的可移植性较差,而且不太可能在Perl等高级语言中使用。