AES-NI 内部函数默认启用?

2022-09-01 09:55:01

Oracle对Java 8在AES-NI方面有这样的说法:

添加了硬件内部函数以使用高级加密标准 (AES)。UseAES 和 UseAESIntrinsics 标志可用于为英特尔硬件启用基于硬件的 AES 内部函数。硬件必须是 2010 或更新的 Westmere 硬件。例如,要启用硬件 AES,请使用以下标志:

-XX:+UseAES -XX:+UseAESIntrinsics

要禁用硬件 AES,请使用以下标志:

-XX:-UseAES -XX:-UseAESIntrinsics

但它并不指示默认情况下是否启用了 AES 内部函数(对于支持它的处理器)。所以问题很简单:如果处理器支持AES-NI,是否使用AES内部函数?

奖励问题:有没有办法测试是否正在使用AES-NI?我想你可以根据性能来猜测,但这不是一种最佳或确定的测试方式。


对于不熟悉AES-NI内部函数的读者:它使用AES-NI指令集用预编译的机器代码替换字节码。这发生在JVM中,因此它不会显示在Java运行时或字节码的API中。


答案 1

该标志的默认值为 true,如果检测失败,它将设置为 false,因此您只需使用 +PrintFlagsFinal 即可查看是否使用了该标志:

我的笔记本电脑没有AES-NI:

C:\>"C:\Program Files\Java\jdk1.7.0_51\bin\java" -XX:+PrintFlagsFinal -version | find "UseAES"
     bool UseAES                                    = false           {product}
     bool UseAESIntrinsics                          = false           {product}
java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

在带有AES-NI的台式机上相同:

C:\>"C:\Program Files\Java\jdk7\bin\java" -XX:+PrintFlagsFinal -version | find "AES"
     bool UseAES                                    = true            {product}
     bool UseAESIntrinsics                          = true            {product}

java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

C:\>"C:\Program Files (x86)\Java\jre7\bin\java" -XX:+PrintFlagsFinal -version | find "AES"
     bool UseAES                                    = true            {product}
     bool UseAESIntrinsics                          = true            {product}

java version "1.7.0_51"
Java(TM) SE Runtime Environment (build 1.7.0_51-b13)
Java HotSpot(TM) Client VM (build 24.51-b03, mixed mode, sharing)

因此,它适用于x64和i686(WOW64)以及最近的Java 7。该功能随 https://bugs.openjdk.java.net/browse/JDK-7184394 一起引入,并向后移植到 7u40 和 7u45。


重要提示:AES-NI 可能仅在服务器虚拟机上可用。

Oracle在提交错误报告后承认了这一点。当他们创建Java 8的featues列表时,这个重要的信息丢失了(后来它也被向后移植到7)。可以通过在 或 命令行上提供选项来显式选择服务器 VM。-serverjavajavaw


答案 2

这个来自openjdk的邮件线程说,默认情况下,所有AES内部函数都处于启用状态。虽然我不确定Oracle核心VM代码与openjdk共享多少。如果您阅读了整个线程,它们还会讨论 32 位 VM 上的挑战,这可能解释了您在第二次测试运行时遇到的问题。

  • 关于您的测试,您不认为CPU的差异会产生很大的不同吗?Core i7是四核的,通常具有更好的时钟速度。这难道不会有所作为吗?我猜想从21s(酷睿i5,32bitVM,AES-NI关闭)到8s(酷睿i7,64bitVM,AES-NI关闭)的转变是i5和i7之间的区别。
  • 从8秒到3秒的改进,虽然不是7倍,但确实值得一个“Yipes”!:)
  • 关于检测机制 - 似乎没有直接的方法。JVM 会抛出警告“AES 内部函数在此 CPU 上不可用”,如果您启用了这些标志,并且如果它找不到 AES 支持 - 根据此错误报告

推荐