【问题标题】:Java performance issue On Oracle LinuxOracle Linux 上的 Java 性能问题
【发布时间】:2021-09-13 06:35:16
【问题描述】:

我正在运行非常“简单”的测试。

@Fork(value = 1, jvmArgs = { "--illegal-access=permit", "-Xms10G", "-XX:+UnlockDiagnosticVMOptions", "-XX:+DebugNonSafepoints", "-XX:ActiveProcessorCount=7",
        "-XX:+UseNUMA"
        , "-XX:+UnlockDiagnosticVMOptions", "-XX:DisableIntrinsic=_currentTimeMillis,_nanoTime",

        "-Xmx10G", "-XX:+UnlockExperimentalVMOptions", "-XX:ConcGCThreads=5", "-XX:ParallelGCThreads=10", "-XX:+UseZGC", "-XX:+UsePerfData", "-XX:MaxMetaspaceSize=10G", "-XX:MetaspaceSize=256M"}
)
    @Benchmark
    public String generateRandom() {
        return UUID.randomUUID().toString();
    }

可能不是很简单,因为使用随机,但同样的问题出现在任何其他使用 java 的测试中

在我的家庭桌面上

Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz 12 Threads (hyperthreading enabled ), 64 GB Ram, "Ubuntu" VERSION="20.04.2 LTS (Focal Fossa)"
Linux homepc 5.8.0-59-generic #66~20.04.1-Ubuntu SMP Thu Jun 17 11:14:10 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux

7 线程的性能:

Benchmark                                            Mode  Cnt        Score       Error   Units
RulesBenchmark.generateRandom                       thrpt    5  1312295.357 ± 27853.707   ops/s

Flame Graph with AsyncProfiler Result with 7 Thread At Home

我在 Oracle Linux 上遇到问题

Linux  5.4.17-2102.201.3.el8uek.x86_64 #2 SMP Fri Apr 23 09:05:57 PDT 2021 x86_64 x86_64 x86_64 GNU/Linux
Intel(R) Xeon(R) Gold 6258R CPU @ 2.70GHz with 56 Threads(hyperthreading disabled, the same when enabled and there is 112 cpu threads ) and 1 TB RAM I have half of performance (Even increasing threads) NAME="Oracle Linux Server" VERSION="8.4"

只有 1 个线程,我的表现非常出色:

Benchmark                                            Mode  Cnt        Score      Error   Units
RulesBenchmark.generateRandom                       thrpt    5  2377471.113 ± 8049.532   ops/s

Flame Graph with AsyncProfiler Result 1 Thread 但是有 7 个线程

Benchmark                                            Mode  Cnt       Score       Error   Units


RulesBenchmark.generateRandom                       thrpt    5  688612.296 ± 70895.058   ops/s

Flame Graph with AsyncProfiler Result 7 Thread

可能是 NUMA 的问题,因为有 2 个 Socket,系统配置只有 1 个 NUMA 节点 numactl --硬件

available: 1 nodes (0)
node 0 cpus: 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
node 0 size: 1030835 MB
node 0 free: 1011029 MB
node distances:
node   0 
  0:  10 

但是在禁用一些 cpu 线程后使用:

for i in {12..55}
do
 # your-unix-command-here
  echo '0'| sudo tee /sys/devices/system/cpu/cpu$i/online
done

性能提升不大,不多。

这只是非常“简单”的测试。在使用真实代码进行复杂测试时,它甚至是值得的, 花了很多时间在.annobin___pthread_cond_signal.start

我还在我的家庭桌面上部署了具有相同版本 Oracle Linux 和内核版本的 vagrant 映像,并使用 10 个 cpu 线程运行它,性能几乎与我的桌面上相同(~1M op/sec)。所以这不是关于操作系统或内核,而是一些配置

通过多个 jDK 版本和供应商(jdk 11 及更高版本)进行测试。使用 YUM 发行版中的 OpenJDK 11 时性能非常少,但并不显着。

你能给我一些建议吗 提前致谢

【问题讨论】:

    标签: linux ubuntu jmh oraclelinux async-profiler


    【解决方案1】:

    本质上,您的基准测试了SecureRandom 的吞吐量。默认实现是synchronized(更准确地说,默认实现混合了输入形式/dev/urandom和上述提供者)。

    矛盾的是,更多的线程会导致更多的争用,从而降低整体性能,因为算法的主要部分无论如何都处于全局锁定之下。 Async-profiler 确实表明瓶颈是 Java 监视器上的同步:__lll_unlock_wake、__pthread_cond_wait、__pthread_cond_signal - 都来自该同步。

    争用开销肯定取决于硬件、固件和操作系统配置。而不是试图减少这种开销(这可能很难,因为,你知道,总有一天会出现另一个安全补丁,这将使系统调用慢 2 倍,例如),我建议首先摆脱争用地点。

    这可以通过安装不同的非阻塞SecureRandom 提供程序来实现,如this answer 所示。我不会就特定的SecureRandomSpi 给出建议,因为这取决于您的具体要求(吞吐量/可扩展性/安全性)。只会提到一个实现可以基于

    【讨论】:

    • 安德烈,非常感谢您抽出时间来看看我的问题。正如我所说,这只是“简单测试”。我有“securerandom.source=file:/dev/urandom”。如果您查看stackoverflow.com/questions/67845210/drools-performance,就会出现同样的问题。我在这台服务器上进行的任何测试,我得到了近 3 倍的低性能
    • @DimitriGamkrelidze 与the linked question 不同,这个看起来足够具体——我希望我回答了有关 SecureRandom 可扩展性的具体问题。如果您最初的问题与 RNG 无关,这意味着您的 minimal example 不够小。从“2+2”测试开始。它真的也慢了 3 倍吗?
    • 你是对的,这个例子不够“简单”来衡量性能,如果你看到了,我写道“可能不是很简单,因为使用随机,但同样的问题在任何其他用 java 测试“。谢谢你的答案。这是要点gist.github.com/ditogam/eab68c5ea69f49e6decd6ed85952df9b,您会看到使用 AtomicInteger 没有任何问题,同步和 ReentrantLock 块有显着不同的结果
    • 无论如何。感谢您花时间详细回答,您回答的方式,您所看到的。这是我的错,我为问题提供了不好的例子:)
    • @DimitriGamkrelidze 事实上,从您的基准测试中可以得出一个很好的结论:原子比锁的扩展性好得多。在 7 个线程中运行一个固有的单线程测试用例没有多大意义,除了证明锁争用很糟糕。您可能想知道为什么它在服务器上比在家用笔记本电脑上更糟糕,但在我看来,这并不重要。这可以是 CPU 频率、内存访问成本、系统调用审计或其他随机的东西——没关系。从定义上讲,争用是不好的,所以尽量减少争用,或者更好的是,完全摆脱它。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-02-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-25
    • 2018-04-07
    相关资源
    最近更新 更多