java的prefetch(),JVM / JAVA中的预取指令

Java Hotspot JVM 实际上支持预取操作,它将 Unsafe 的 prefetchRead 和 prefetchWrite 方法作为内联处理,转化为相应的CPU指令。尽管sun.misc.Unsafe没有声明这些方法,但通过修改Unsafe.java并重新编译,可以启用预取内联。然而,在JDK9中,预取内联已经被完全移除,因为实验结果显示其对性能提升效果不明显。
摘要由CSDN通过智能技术生成

Is there any software prefetching instructions in Java language or JVM, like __builtin_prefetch which is available in GCC

解决方案

One interesting thing is that Hotspot JVM actually does support prefetch!

It treats Unsafe.prefetchRead() and Unsafe.prefetchWrite() methods as intrinsics and compiles them into corresponding CPU instructions.

Unfortunately, sun.misc.Unsafe does not declare such methods. But, if you add the following methods to Unsafe.java, recompile it and replace Unsafe.class inside rt.jar (or just add -Xbootclasspath/p JVM argument) you would be able to use prefetch intrinsics in your application.

public native void prefetchRead(Object o, long offset);

public native void prefetchWrite(Object o, long offset);

public static native void prefetchReadStatic(Object o, long offset);

public static native void prefetchWriteStatic(Object o, long offset);

I doubt this could help much in real applications, but if you'd like to play with it, I can provide more details.

Here is a compiled patch to JDK 8 that enables prefetch methods: download

Usage example:

long[] array = new long[100*1024*1024];

// ...

sun.misc.Unsafe.prefetchReadStatic(array, 50*1024*1024);

UPDATE

Unsafe.prefetch* intrinsics are completely removed in JDK 9:

Note read/write prefetch support was implemented as an experiment to

see if JDK library code could use it for performance advantages.

However, the results of the experiment did not indicate this was

worthwhile. As a consequence there are no corresponding prefetch

native method declarations in sun.misc.Unsafe.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenBLAS可以使用不同的取指令取一部分矩阵的数据。其,L1级别的取指令可以取矩阵相邻的一行或一列的数据,L2级别的取指令可以取相邻的一块矩阵的数据,L3级别的取指令可以取更大的矩阵块的数据。具体来说,可以使用以下函数来实现OpenBLAS取操作: ```c void cblas_sgemm(const enum CBLAS_ORDER Order, const enum CBLAS_TRANSPOSE TransA, const enum CBLAS_TRANSPOSE TransB, const int M, const int N, const int K, const float alpha, const float *A, const int lda, const float *B, const int ldb, const float beta, float *C, const int ldc); ``` 其,M、N、K表示矩阵的维度,A、B、C表示矩阵的数据,alpha、beta表示矩阵乘法的系数,lda、ldb、ldc表示矩阵的存储格式和布局。 举例来说,如果要取矩阵A的第一行数据,可以使用以下代码: ```c #define L1_CACHE_LINE_SIZE 64 float A[M*K]; float B[K*N]; float C[M*N]; for (int i = 0; i < M; i++) { __builtin_prefetch(&A[i*K], 0, 1); // 取A的第i行数据 } cblas_sgemm(CblasRowMajor, CblasNoTrans, CblasNoTrans, M, N, K, alpha, A, K, B, N, beta, C, N); ``` 在上面的代码,__builtin_prefetch函数用于取矩阵A的第i行数据。这里使用了L1级别的取指令,第二个参数为0表示取到L1缓存,第三个参数为1表示取读取数据后立即触发数据传输,即取A的下一行数据。需要注意的是,在使用取指令时,应该根据实际情况进行调整,以避免对性能产生负面影响。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值