成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

CPU Cache偽共享問題

開發 架構
如果x和y中間加了128字節的填充,x和y不在同一個Cache line上,不同CPU之前不會影響,它倆都會頻繁的命中自己的Cache,整個程序性能就會很高,這就是傳說中的False Sharing問題。

先看下這兩段代碼:

代碼段1:

const int row = 10240;
const int col = 10240;
int matrix[row][col];
int TestRow() {
//按行遍歷
int sum_row = 0;
for (int r = 0; r < row; r++) {
for (int c = 0; c < col; c++) {
sum_row += matrix[r][c];
}
}
return sum_row;
}

代碼段2:


int TestCol() {
//按列遍歷
int sum_col = 0;
for (int c = 0; c < col; c++) {
for (int r = 0; r < row; r++) {
sum_col += matrix[r][c];
}
}
return sum_col;
}

兩段代碼的目的相同,都是為了計算矩陣中所有元素的總和。

但有些區別:一個是按行遍歷元素做計算,一個是按列遍歷元素做計算。

它倆的運行速度有什么區別嗎?

如圖:

圖片

圖片

圖中可以看到,行遍歷的代碼速度比列遍歷的代碼速度快很多。

為什么按行遍歷的代碼比按列遍歷的代碼速度快?這里就是CPU Cache在起作用。

什么是CPU Cache?

可以先看下這個存儲器相關的金字塔圖:

圖片

從下到上,空間雖然越來越小,但是處理速度越來越快,相應的,設備價格也越來越貴。

圖中的寄存器和主存估計大家都知道,那中間的L1 、L2、L3是什么?它們起到了什么作用?

它們就是CPU 的Cache,如下圖:

圖片

可以理解為CPU Cache就是CPU與主存之間的橋梁。

當CPU想要訪問主存中的元素時,會先查看Cache中是否存在,如果存在(稱為Cache Hit),直接從Cache中獲取,如果不存在(稱為Cache Miss),才會從主存中獲取。Cache的處理速度比主存快得多。

所以,如果每次訪問數據時,都能直接從Cache中獲取,整個程序的性能肯定會更高。

那,如何提高CPU Cache的命中率?

這里我不多介紹,感興趣的直接移步到我這篇文章:https://mp.weixin.qq.com/s/iKWQZxn6XYKU9KnlBRynfg

但CPU Cache這里還有個小問題,看下這兩段代碼:

代碼段1:


struct Point {
std::atomic<int> x;
// char a[128];
std::atomic<int> y;
};
void Test() {
Point point;
std::thread t1(
[](Point *point) {
for (int i = 0; i < 100000000; ++i) {
point->x += 1;
}
},
&point);
std::thread t2(
[](Point *point) {
for (int i = 0; i < 100000000; ++i) {
point->y += 1;
}
},
&point);
t1.join();
t2.join();
}

代碼段2:

struct Point {
std::atomic<int> x;
char a[128];
std::atomic<int> y;
};
void Test() {
Point point;
std::thread t1(
[](Point *point) {
for (int i = 0; i < 100000000; ++i) {
point->x += 1;
}
},
&point);
std::thread t2(
[](Point *point) {
for (int i = 0; i < 100000000; ++i) {
point->y += 1;
}
},
&point);
t1.join();
t2.join();
}

兩端代碼的核心邏輯都是對Point結構體中的x和y不停+1。只有一點區別就是在中間塞了128字節的數組。

它們的執行速度卻相差很大。

圖片

圖片

帶128的比不帶128的代碼,執行速度快很多。

為什么?

看過我上面文章的同學應該就知道,每個CPU都有自己的L1和L2 Cache,而Cache line的大小一般是64字節,如果x和y之間沒有128字節的填充,它倆就會在同一個Cache line上。

代碼中開了兩個線程,兩個線程大概率會運行在不同的CPU上,每個CPU有自己的Cache。

當CPU1操作x時,會把y裝載到Cache中,其他CPU對應的的Cache line失效。

然后CPU2加載y,會觸發Cache Miss,它后面又把x裝載到了自己的Cache中,其他CPU對應的Cache line失效。

然后CPU1操作x時,又觸發Cache Miss。

它倆就會是大體這個流程:

圖片

頻繁的觸發Cache Miss,導致程序的性能相當差。

而如果x和y中間加了128字節的填充,x和y不在同一個Cache line上,不同CPU之前不會影響,它倆都會頻繁的命中自己的Cache,整個程序性能就會很高,這就是傳說中的False Sharing問題。

所以我們寫代碼時,可以基于此做深一層思考,如果我們寫單線程程序,最好保證訪問的數據能夠相鄰,在一個Cache line上,可以盡可能的命中Cache。

如果寫多線程程序,最好保證訪問的數據有間隔,讓它們不在一個Cache line上,減少False Sharing的頻率。

上述內容源于前一段的技術分享,完整PPT在 一個優質的C++學習圈 里,來一起鉆研C++吧。?

責任編輯:武曉燕 來源: 程序喵大人
相關推薦

2019-01-15 14:44:02

CPU Cache L共享存儲器

2019-12-17 14:24:11

CPU緩存偽共享

2023-08-01 08:10:46

內存緩存

2022-02-02 21:50:25

底層偽共享CPU

2017-07-13 16:40:16

偽共享緩存行存儲

2022-01-17 14:24:09

共享字節面試

2021-11-18 08:55:49

共享CPU內存

2024-06-27 08:33:37

2013-07-30 10:46:39

CPU Cache并發

2017-08-23 13:21:31

2023-12-26 10:08:57

緩存偽共享修飾結構體

2021-03-01 11:53:15

面試偽共享CPU

2018-11-30 15:17:38

CPUCache緩存行

2021-06-30 21:13:49

CPUCache數據

2013-06-14 10:12:22

共享并行

2022-08-17 06:25:19

偽共享多線程

2023-09-07 14:04:58

計算機CPU內存

2023-08-02 09:28:28

計算機性能CPU

2019-01-04 10:53:59

CPUCache緩存

2015-08-17 14:53:44

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 免费看黄色视屏 | 国产精品福利在线 | 久久久69 | 成人影院网站ww555久久精品 | 先锋资源吧 | 久久亚洲综合 | 欧美lesbianxxxxhd视频社区 | 这里精品| 国产xxxx搡xxxxx搡麻豆 | 视频一区二区三区在线观看 | 在线观看黄视频 | 亚洲精品成人av | 亚洲欧美一区二区在线观看 | 国产一区二区视频免费在线观看 | 天天操人人干 | 国产xxxx在线 | 久久91av | 国产av毛片 | 国产欧美一区二区三区在线看蜜臀 | 久久91| 国产a区 | 欧美成人精品激情在线观看 | 国产黑丝av| 96av麻豆蜜桃一区二区 | 亚洲精品一区二区在线观看 | av成人在线观看 | 国产成人亚洲精品 | 亚洲国产一区二区三区在线观看 | 蜜桃色网 | 亚洲国产精品人人爽夜夜爽 | 久热爱| 日韩在线视频免费观看 | 国产精品国产三级国产aⅴ入口 | 成人欧美一区二区三区黑人孕妇 | 欧美精品一区二区三区四区 在线 | 白浆在线 | 毛片视频网址 | 中文字幕二区 | 99久久亚洲 | 三区在线| 久久国产精品久久 |