2013-08-13 11 views
11

背景sun.misc.Unsafeを使用すると、Direct ByteBufferからバイトをスキャンする最も速い方法は何ですか?

私は直接のByteBufferを有すると仮定:

ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024); 

及びIはXまでそのソケットからデータのチャンクを読み取ることAsynchronousSocketChannelにバッファを通過してい仮定1024(時バイトここの例では)。

へのソケットからの転送時間 ByteBufferは、ネイティブOSのメモリ空間ですべて発生しているので幻想的です。私は

QUESTION

が私の仕事は、直接バイトバッファから後ろに読み込まれたすべてのバイトをスキャンすることであると仮定すると...まだJVM「血液脳」関門を通過していない、何があります 最速私はこれを行う方法ですか?

私はもともと「... sun.misc.Unsafeを利用しています」と尋ねましたが、それは誤った仮定です。 POSSIBLE

私は現在、3つのアプローチを見て、私はおよそ最も好奇心1が3位である

に近づく:

  1. (DEFAULT)の使用のByteBufferのbulk-getにネイティブOS空間から直接バイトを引っ張って内部のbyte [1024]構造体です。
  2. (UNSAFE)UnsafeのgetByte opsを使用すると、ByteBufferの標準get操作のすべての境界チェックをスキップしてByteBufferから直接値を引き出すことができます。 Peter Lawreyの回答hereは、Unsafeの未加工のネイティブメソッドをJITコンパイラ(「組み込み関数」)によって単一のマシン命令に最適化して、さらに素晴らしいアクセス時間につなげることができるように思われました。安全でない方法を使用しての(=== === UPDATE面白い、基礎となるDirectByteBufferクラスは、興味のある人のためのget/put opsと正確にこれを行うように見えます。)
  3. (バナナ)いくつかの中で犯罪に対する-人類の並べ替え、直接のByteBufferのcopy the memory regionを同じメモリアドレスにすることができますか?私のバイト[1024]はVMの内部に存在し、標準のintインデックスを使用して配列にアクセスし始めますか? (これは、「copyMemory」操作が潜在的に素晴らしく、OSレベルで最適化された何かを行うことができますことを仮定します。

copyMemoryを仮定すると、操作が一層で、それがアドバタイズまさにないように私には発生しません最適なOSスペース。バッファの複製を作成する前に、上記の#2アプローチがおそらく最も最適化されている可能性があります。

これは「can I use Unsafe to iterate over a byte[] faster?」の質問とは異なります必要でなければバイトを内部的にバイト[]にプルする計画。

ありがとうございました。誰か(Peter?)がUnsafeと一緒にこのようなことをしているのであれば好奇心が強い。

答えて

1

ByteBufferこれらのメソッドは組み込み関数であるため、メソッドは非常に高速です.VMはそれらを非常に低レベルの命令にマップしています。

byte[] bytes = new byte[N]; 
    for(int m=0; m<M; m++) 
     for(int i=0; i<bytes.length; i++) 
      sum += bytes[i]; 

    ByteBuffer bb = ByteBuffer.allocateDirect(N); 
    for(int m=0; m<M; m++) 
     for(int i=0; i<bb.remaining(); i++) 
      sum += bb.get(i); 

私のマシンでは、違いは0.67nsと0.81ns(ループごと)です。

ByteBufferがbyte []ほど速くないのは少し驚いています。しかし、私はあなたが間違いなくそれをバイト[]にコピーしてからアクセスするべきではないと思います。

+0

ByteBufferメソッドの「組み込みの」プロパティについて知りませんでした。 DirectBufferクラスの「ネイティブ」メソッドを具体的に意味しますか?その場合、それは#2が私のポストの中でやることとまったく同じことになるでしょう。それはすばらしいニュースです。 –

+0

@RiyadKalla intrinsic!=ネイティブ。組み込みメソッドは、JVMで「ハードコード」されています。 – assylias

+0

@assylias私は理解しています。私は(間違って)DirectByteBuffer implクラスの「ネイティブ」メソッドであると考えたものを参照していました(http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java /nio/DirectByteBuffer.java)しかし、私はそれを見ているので、「ネイティブ」メソッドがないことが分かります。単純にUnsafeを利用してこれらの操作を行うだけです。私は間違っている、キャッチのためにありがとう。 –

関連する問題