gpt4 book ai didi

java - ByteBuffer.putLong 使用非原生 ByteOrder 快 2 倍

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:16:37 24 4
gpt4 key购买 nike

尽管广泛阅读了 JDK 源代码并检查了内在例程,但我还是无法完全理解这个结果。

我正在测试清除 ByteBuffer,使用 ByteBuffer.putLong(int index, long value) 通过 allocateDirect 分配。基于 JDK 代码,如果缓冲区处于“ native 字节顺序”,这将导致单个 8 字节写入,或者字节交换,如果不是,则后跟相同。

所以我希望 native 字节顺序(对我来说是小端)至少与非 native 一样快。然而,事实证明,非本地人的速度快了约 2 倍。

这是我在 Caliper 0.5x 中的基准测试:

...    

public class ByteBufferBench extends SimpleBenchmark {

private static final int SIZE = 2048;

enum Endian {
DEFAULT,
SMALL,
BIG
}

@Param Endian endian;

private ByteBuffer bufferMember;

@Override
protected void setUp() throws Exception {
super.setUp();
bufferMember = ByteBuffer.allocateDirect(SIZE);
bufferMember.order(endian == Endian.DEFAULT ? bufferMember.order() :
(endian == Endian.SMALL ? ByteOrder.LITTLE_ENDIAN : ByteOrder.BIG_ENDIAN));
}

public int timeClearLong(int reps) {
ByteBuffer buffer = bufferMember;
while (reps-- > 0) {
for (int i=0; i < SIZE / LONG_BYTES; i+= LONG_BYTES) {
buffer.putLong(i, reps);
}
}
return 0;
}

public static void main(String[] args) {
Runner.main(ByteBufferBench.class,args);
}

}

结果是:

benchmark       type  endian     ns linear runtime
ClearLong DIRECT DEFAULT 64.8 =
ClearLong DIRECT SMALL 118.6 ==
ClearLong DIRECT BIG 64.8 =

这是一致的。如果我将 putLong 换成 putFloat,它的原生顺序大约快 4 倍。如果你看看 putLong 是如何工作的,它在非本地情况下做的工作绝对更多:

private ByteBuffer putLong(long a, long x) {
if (unaligned) {
long y = (x);
unsafe.putLong(a, (nativeByteOrder ? y : Bits.swap(y)));
} else {
Bits.putLong(a, x, bigEndian);
}
return this;
}

请注意,unaligned 在任何一种情况下都是正确的。 native 和非 native 字节顺序之间的唯一区别是 Bits.swap,它有利于 native 大小写(小端)。

最佳答案

总结机械同情邮件列表中的讨论:

1.OP 描述的异常在我的设置 (JDK7u40/Ubuntu13.04/i7) 上无法重现,导致在所有情况下堆和直接缓冲区的性能一致,直接缓冲区提供巨大的性能优势:

BYTE_ARRAY DEFAULT 211.1 ==============================
BYTE_ARRAY SMALL 199.8 ============================
BYTE_ARRAY BIG 210.5 =============================
DIRECT DEFAULT 33.8 ====
DIRECT SMALL 33.5 ====
DIRECT BIG 33.7 ====

Bits.swap(y) 方法被内在化为一条指令,因此不能/不应该真正解释很多差异/开销。

2.上述结果(即与 OP 经验相矛盾)由另一位参与者编写的 naive hand rolled benchmark 和 JMH benchmark 独立确认。

这让我相信您遇到了一些本地问题或某种基准测试框架问题。如果其他人可以运行该实验并查看他们是否可以重现您的结果,那将很有值(value)。

关于java - ByteBuffer.putLong 使用非原生 ByteOrder 快 2 倍,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19265835/

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