这代码居然有差别?CPU友好的代码该这样写(4)

简介: 这代码居然有差别?CPU友好的代码该这样写

三、总结


再来回顾一下我们之前的问题。

image.png

C代码块 是横向优先的访问方式。

A代码块 里面对 arrays_A 的方式是横向顺序访问的,但是在处理 arrays_B 的时候就是纵向遍历的。

B代码块 所有的访问都是纵向的(不友好的遍历方式)。因为发挥不出CPU缓存的效果,所以性能最差。

Java的二维数组在内存里面是行连续的,但是行与行之间不一定连续。CPU在缓存大小有限的情况下,不可能把所有的数据都缓存下来。再加上每一层级访问速度的硬件限制,就导致了上面的性能结果。

相信大家也和我一样,知道原理之后,也不是那么迷惑了。

在实际的业务环境中,我们不一定能遇到这种纯计算的场景。但是我们还是应该尽量顺序访问数据,不管是什么样的数据。投其所好,方能够优化代码性能。

其次,我们在访问数据的时候,还是需要了解各种语言背后实际的存储结构和CPU的缓存原理,本次是讲述的是Java,但是这个思想其他语言其实也是受用的。


四、附件

4.1 运行的环境

系统参数:

JMH version: 1.36

VM version: JDK 11.0.13, Java HotSpot(TM) 64-Bit Server VM, 11.0.13+10-LTS-370

JMH version: 1.36
VM version: JDK 11.0.13,Java HotSpot(TM) 64-Bit Server VM,11.0.13+10-
型号名称:MacBook Pro
型号标识符:MacBookPro15,2
处理器名称:四核Intel Core i5
处理器速度: 2.4 GHz
处理器数目: 1
核总数: 4
L2缓存 (每个核) : 256 KB
L3缓存:6 MB
超线程技术:已启用
内存:16 GB
系统固件版本: 1715.60.5.0.0 (iBridge: 19.16.10647.0.0,0)


4.2 整个benchmark的java代码

ArrayTestBenchmark

import org.openjdk.jmh.annotations.*;
/**
*矩阵C=AB 的计算
*
* @author wzj*
* @date 2023/02/09
*/
@BenchmarkMode(Mode.AverageTime)
@State(value = Scope.Benchmark)
// 预热3次
@Warmup(iterations = 3, time = 1)
// 循环 10 次
@Measurement(iterations = 10, time = 1)
public class ArrayTestBenchmark {
private final int N = 1000;
private final int[][] arrays_A = new int[N][N];
private final int[][] arrays B = new int[N][N];
@Setup
public void setUp() {
for (int i=; i< N; i++) {
for (int j =0; j< N; j++) {
arrays_A[i][j] = i + j;
arrays B[i][jl = i + j;
}
}
}
@Benchmark
public void ijk() {
final int[][] arrays_C = new int[N] [N];
for (int i=0; i<N; i++) {
for (int j=0; j < N; j++) {
int sum = 0;
for (int k=0; k < N; k++){
sum += arrays A[i][k] * arrays B[k][j];
}
arrays_C[i][j] += sum;
}
}
assert arrays_C.length > 0;
}
@Benchmark
public void jik(){
final int[][] arrays_C = new int[N][N];
for (int j =@; j< N; j++) {
for (int i=@; i< N; i++) {
int sum = 0;
for (int k =; k< N; k++) {
sum += arrays A[i][k] * arrays B[k][j];
}
arrays_C[i][j] += sum;
}
}
assert arrays_C.length > 0;
}
@Benchmark
public void jki() {
final int[][] arrays_C = new int[N][N];
for (int j =; j < N; j++){
for (int k =0; k< N; k++) {
int r_B = arrays_B[k][j];
for (int i=@; i< N; i++) {
arrays_C[i][j] += arrays_A[i][k] * r_B;
}
}
}
assert arrays_C.length > 0;
}
@Benchmark
public void kji() {
final int[][] arrays_C = new int[N] [N];
for (int k =o; k < N; k++) {
for (int j =@; j < N; j++) {
int r_B = arrays_B[k][j];
for (int i=0; i< N; i++) {
arrays_C[i][j] += arrays A[i][k] * r_B;
}
}
}
assert arrays C.length > 0;
}
@Benchmark
public void kij() {
final int[][] arrays C = new int[N][N];
for (int k =; k < N; k++) {
for (int i=0; i < N; i++) {
int r A = arrays A[k][i];
for (int j=0; j <N; j++) {
arrays_C[i][j] += r_A * arrays_B[k][j];
}
}
}
assert arrays C.length > 0;
}
@Benchmark
public void ikj() {
final int[][] arrays_C = new int[N][N];
for (int i=0; i< N; i++) {
for (int k =o; k < N; k++) {
int r_A = arrays A[k][i];
for (int j =@; j < N; j++) {
arrays_C[i][j] += r_A *arrays_B[k][j];
}
}
}
assert arrays_C.length > 0;
}
}


4.3 多次运行benchmark的结果

image.png

引用:

  1. 《深入理解计算机操作系统》
  2. 《深入理解Java虚拟机》
目录
相关文章
|
Java Linux
linux中找到最耗CPU的那段Java代码
linux中找到最耗CPU的那段Java代码
247 0
|
调度
CPU调度器实现提示:针对特定体系结构代码【ChatGPT】
CPU调度器实现提示:针对特定体系结构代码【ChatGPT】
|
并行计算 异构计算 Python
python代码torch.device("cuda:0" if torch.cuda.is_available() else "cpu")是什么意思?
【6月更文挑战第3天】python代码torch.device("cuda:0" if torch.cuda.is_available() else "cpu")是什么意思?
2058 4
|
机器学习/深度学习 TensorFlow API
Keras是一个高层神经网络API,由Python编写,并能够在TensorFlow、Theano或CNTK之上运行。Keras的设计初衷是支持快速实验,能够用最少的代码实现想法,并且能够方便地在CPU和GPU上运行。
Keras是一个高层神经网络API,由Python编写,并能够在TensorFlow、Theano或CNTK之上运行。Keras的设计初衷是支持快速实验,能够用最少的代码实现想法,并且能够方便地在CPU和GPU上运行。
|
Java Linux
Linux下如何定位最耗CPU的JAVA代码
Linux下如何定位最耗CPU的JAVA代码
244 0
|
监控 数据可视化 Java
双CPU监控的目的以及主流编程语言实现代码示例
监控CPU使用率可以帮助检测系统瓶颈和性能问题,有助于及时识别并解决故障。
689 2
|
监控 调度 Python
电脑监控软件所含的CPU资源监控的代码(使用psutil库)
本文使用psutil库来获取CPU使用率、运行的进程、CPU温度、风扇速度和CPU核心的工作情况。这些信息可用于自定义电脑监控软件的CPU资源监控功能
884 1
|
6月前
|
缓存 人工智能 算法
不同业务怎么选服务器?CPU / 内存 / 带宽配置表
本文详解了服务器三大核心配置——CPU、内存、带宽,帮助读者快速理解服务器性能原理。结合不同业务场景,如个人博客、电商、数据库、直播等,提供配置选择建议,并强调合理搭配的重要性,避免资源浪费或瓶颈限制。内容实用,适合初学者和业务选型参考。
999 0
|
6月前
|
存储 消息中间件 缓存
从纳秒到毫秒的“时空之旅”:CPU是如何看待内存与硬盘的?
在数据爆炸的时代,如何高效存储与管理海量数据成为系统设计的核心挑战。本文从计算机存储体系结构出发,解析B+树、LSM树与Kafka日志结构在不同数据库中的应用与优化策略,帮助你深入理解高性能存储背后的原理。
213 0
|
8月前
|
存储
阿里云轻量应用服务器收费标准价格表:200Mbps带宽、CPU内存及存储配置详解
阿里云香港轻量应用服务器,200Mbps带宽,免备案,支持多IP及国际线路,月租25元起,年付享8.5折优惠,适用于网站、应用等多种场景。
2744 0

热门文章

最新文章