4

仕様ごとに 10k IOPS 以上を提供する必要がある SSD ディスクがあります。私のベンチマークでは、20k IOPS が得られることが確認されています。

次に、そのようなテストを作成します。

private static final int sector = 4*1024;
private static byte[] buf = new byte[sector];
private static int duration = 10; // seconds to run
private static long[] timings = new long[50000];
public static final void main(String[] args) throws IOException {
    String filename = args[0];
    long size = Long.parseLong(args[1]);
    RandomAccessFile raf = new RandomAccessFile(filename, "r");
    Random rnd = new Random();
    long start = System.currentTimeMillis();
    int ios = 0;
    while (System.currentTimeMillis()-start<duration*1000) {
        long t1 = System.currentTimeMillis();
        long pos = (long)(rnd.nextDouble()*(size>>12));
        raf.seek(pos<<12);
        int count = raf.read(buf);
        timings[ios] = System.currentTimeMillis() - t1;
        ++ios;
    }
    System.out.println("Measured IOPS: " + ios/duration);
    int totalBytes = ios*sector;
    double totalSeconds = (System.currentTimeMillis()-start)/1000.0;
    double speed = totalBytes/totalSeconds/1024/1024;
    System.out.println(totalBytes+" bytes transferred in "+totalSeconds+" secs ("+speed+" MiB/sec)");
    raf.close();
    Arrays.sort(timings);
    int l = timings.length;
    System.out.println("The longest IO = " + timings[l-1]);
    System.out.println("Median duration = " + timings[l-(ios/2)]);
    System.out.println("75% duration = " + timings[l-(ios * 3 / 4)]);
    System.out.println("90% duration = " + timings[l-(ios * 9 / 10)]);
    System.out.println("95% duration = " + timings[l-(ios * 19 / 20)]);
    System.out.println("99% duration = " + timings[l-(ios * 99 / 100)]);
}

そして、この例を実行すると、ちょうど 2186 IOPS が得られます。

$ sudo java -cp ./classes NioTest /dev/disk0 240057409536
Measured IOPS: 2186
89550848 bytes transferred in 10.0 secs (8.540234375 MiB/sec)
The longest IO = 35
Median duration = 0
75% duration = 0
90% duration = 0
95% duration = 0
99% duration = 0

Cでの同じテストよりもずっと遅いのはなぜですか?

更新: 20k IOPS を提供する Python コードは次のとおりです。

def iops(dev, blocksize=4096, t=10):

    fh = open(dev, 'r')
    count = 0
    start = time.time()
    while time.time() < start+t:
        count += 1
        pos = random.randint(0, mediasize(dev) - blocksize) # need at least one block left
        pos &= ~(blocksize-1)   # sector alignment at blocksize
        fh.seek(pos)
        blockdata = fh.read(blocksize)
    end = time.time()
    t = end - start
    fh.close()

Update2 : NIO コード (ほんの一部、すべてのメソッドを複製するわけではありません)

...
RandomAccessFile raf = new RandomAccessFile(filename, "r");
InputStream in = Channels.newInputStream(raf.getChannel());
...
int count = in.read(buf);
...
4

4 に答える 4

4

この記事とその日付によると、従来の Java ランダム アクセスは 2.5 ~ 3.5 倍遅くなります。これは研究用の pdf ですので、クリックしたことで私を責めないでください。

リンク: http://pages.cs.wisc.edu/~guo/projects/736.pdf

Java の raw I/O は C/C++ よりも低速です。これは、Java のシステム コールがより高価であるためです。バッファリングはシステムコールを減らすため、Java I/O パフォーマンスを向上させますが、バッファサイズを大きくしても大きなメリットはありません。ダイレクト バッファリングは、Java 提供のバッファ付き I/O クラスよりも優れています。ユーザーが自分のニーズに合わせて調整できるからです。操作サイズを大きくすると、オーバーヘッドなしで I/O パフォーマンスが向上します。また、システム コールは Java ネイティブ メソッドでは低コストですが、ネイティブ メソッドを呼び出すオーバーヘッドはかなり高くなります。ネイティブ呼び出しの数を適切に削減すると、C/C++ に匹敵するパフォーマンスを実現できます。

その時代からあなたのコードです。RandomAccessFileでは、を使用せずに書き直してみましょうjava.nio

Cに対してピットインできるnio2コードがいくつかあります。ガベージコレクションは除外できます:)

于 2015-06-28T00:06:23.407 に答える
1

RandomAccess は Java ではほとんど高速ですが、C と比較することはできません。しかし、JVM での IO パフォーマンスのより良い比較が必要な場合は、このテーマに関する Martin Thompson の優れたブログをお読みください: http://mechanical-sympathy.blogspot.co.uk /2011/12/java-順次-io-performance.html

于 2015-06-28T23:04:01.017 に答える
1

RandomAccessFileJava でディスク I/O の最も遅い方法の 1 つである を使用しているためです。

BufferedInputStreamやなどのより高速なものを使用してみて、BufferedOutputStreamどのくらいの速度が得られるかを確認してください。

なぜこれが SSD で違いを生むのか疑問に思っているなら (SSD はランダム アクセスに優れていると考えられているため)、それはアクセスのランダム性に関するものではありません。それは帯域幅についてです。1024 ビット幅のバスを備えた SSD を使用しているが、1 回の書き込みで 64 ビットしか書き込んでいない場合 ( longs またはdoubles を書き込んでいる場合と同様)、速度が遅くなります。(もちろん、これらの数値は単なる例です。)

さて、それはあなたのコードが行っていることではない (または、少なくとも行っているように見える) ことがわかりますが、RandomAccessFile内部でそのように実装されている可能性は十分にあります。もう一度、バッファリングされたストリームを試して、何が起こるか見てみましょう。

于 2015-06-27T23:01:51.423 に答える