gpt4 book ai didi

java - 使用 sun.misc.Unsafe,从 Direct ByteBuffer 扫描字节的最快方法是什么?

转载 作者:搜寻专家 更新时间:2023-10-30 21:34:57 26 4
gpt4 key购买 nike

背景

假设我有一个直接的 ByteBuffer:

ByteBuffer directBuffer = ByteBuffer.allocateDirect(1024);

并假设我将缓冲区传递给 AsynchronousSocketChannel一次从该套接字读取最多 X 字节的数据 block (此处示例中为 1024)。

从套接字到直接 ByteBuffer 的传输时间非常好,因为它全部发生在 native 操作系统内存空间中;我还没有通过JVM“血脑”屏障......

问题

假设我的工作是扫描从直接字节缓冲区读回的所有字节,我执行此操作的最快方法是什么?

我最初问“... 利用 sun.misc.Unsafe ”,但也许这是错误的假设。

可能的方法

我目前看到三种方法,我最好奇的一种是#3:

  1. (默认)使用 ByteBuffer 的 bulk-get将字节直接从 native 操作系统空间拉入内部 byte[1024] 结构。
  2. (不安全)使用不安全的 getByte ops 直接从 ByteBuffer 中提取值,跳过 ByteBuffer 的标准 get ops 的所有边界检查。 Peter Lawrey 的回答 here似乎暗示 Unsafe 中的那些原始 native 方法甚至可以通过 JIT 编译器(“内在函数”)优化为单个机器指令,从而导致更出色的访问时间。 (===UPDATE=== 有趣,对于那些感兴趣的人来说,它看起来像底层 DirectByteBuffer 类用 get/put ops 做的。)
  3. (BANANAS) 以某种反人类犯罪的方式,使用 Unsafe,我可以 copy the memory region直接 ByteBuffer 到同一内存地址我的字节 [1024] 存在于 VM 内部,然后开始使用标准 int 索引访问数组? (这假设“copyMemory”操作可能会在操作系统级别做一些非常优化的事情。

我确实想到,假设 copyMemory 操作完全按照它所宣传的那样进行,即使在更优化的操作系统空间中,上面的 #2 方法可能仍然是最优化的,因为我在开始处理之前不要创建缓冲区的副本。

这与“can I use Unsafe to iterate over a byte[] faster?”问题不同,因为如果没有必要,我什至不打算在内部将字节拉入 byte[]。

谢谢你的时间;只是好奇是否有人(Peter?)对 Unsafe 发疯了来做这样的事情。

最佳答案

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[] 快。但我认为你绝对不应该将它复制到 byte[] 然后访问。

关于java - 使用 sun.misc.Unsafe,从 Direct ByteBuffer 扫描字节的最快方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18220435/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com