欧美一区二区三区老妇人-欧美做爰猛烈大尺度电-99久久夜色精品国产亚洲a-亚洲福利视频一区二区

C++ 內(nèi)存模型 write_x_read_y 試?yán)龢?gòu)造

之前一段時間偶然在 B 站上刷到了南京大學(xué)蔣炎巖(jyy)老師在直播操作系統(tǒng)網(wǎng)課。點(diǎn)進(jìn)直播間看了一下發(fā)現(xiàn)這個老師實(shí)力非凡,上課從不照本宣科,而且旁征博引又不吝于親自動手演示,于是點(diǎn)了關(guān)注。后來開始看其網(wǎng)課錄播,其中一節(jié)的標(biāo)題吸引了我,多處理器編程:從入門到放棄 (線程庫;現(xiàn)代處理器和寬松內(nèi)存模型)?!岸嗵幚砥骶幊獭边@個詞讓我聯(lián)想到去年看的《The Art of Multiprocessor Programming》,于是仔細(xì)看了一下這節(jié)網(wǎng)課。里面介紹到了一個試?yán)?write_x_read_y,它是用 C 語言和內(nèi)聯(lián)匯編寫的,它用來說明運(yùn)行期指令重排。這個試?yán)軌虺晒τ^測到運(yùn)行期指令重排現(xiàn)象。這讓我不得不佩服 jyy 的實(shí)踐精神。之前看了一些介紹 C++ 內(nèi)存模型的文章,沒有一個能用可復(fù)現(xiàn)的完整代碼說明問題的,全部都是說這段代碼可能出現(xiàn) xx 結(jié)果,沒有實(shí)際的執(zhí)行結(jié)果。在 C++ 內(nèi)存模型中,這個測試用例除了能夠說明運(yùn)行期指令重排,也能用于說明 happens-before consistency 和 sequential consistency 的差別。于是嘗試用 C++ Atomic 來實(shí)現(xiàn)這段代碼,看看能不能觀測到預(yù)期結(jié)果。

成都創(chuàng)新互聯(lián)從2013年成立,是專業(yè)互聯(lián)網(wǎng)技術(shù)服務(wù)公司,擁有項(xiàng)目網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作網(wǎng)站策劃,項(xiàng)目實(shí)施與項(xiàng)目整合能力。我們以讓每一個夢想脫穎而出為使命,1280元鐵力做網(wǎng)站,已為上家服務(wù),為鐵力各地企業(yè)和個人服務(wù),聯(lián)系電話:13518219792

首先線程庫 pthread 替換為 std::thread,內(nèi)聯(lián)匯編替換為 std::atomic,且 load 和 store 操作全部使用最弱的 std::memory_order_relaxed 內(nèi)存序。完整的代碼如下:

// write_x_read_y.cpp

#include <atomic>
#include <thread>
#include <stdio.h>

static std::atomic_int flag{0};

inline void wait_flag(int id)
{
    while (!(flag & (0x1 << id))) {}
}

inline void clear_flag(int id)
{
    flag.fetch_and(~(0x1 << id));
}

std::atomic_int x{0}, y{0};

void write_x_read_y()
{
    while (true) {
        wait_flag(0);

        x.store(1, std::memory_order_relaxed);    // t1.1
        int v = y.load(std::memory_order_relaxed); // t1.2
        printf("%d ", v);

        clear_flag(0);
    }
}

void write_y_read_x()
{
    while (true) {
        wait_flag(1);

        y.store(1, std::memory_order_relaxed);    // t2.1
        int v = x.load(std::memory_order_relaxed); // t2.2
        printf("%d ", v);

        clear_flag(1);
    }
}

int main()
{
    std::thread t1(write_x_read_y), t2(write_y_read_x);

    while (true) {
        x = 0, y = 0;
        flag = 0b11;

        while (flag) {}

        printf("\n");
        fflush(stdout);
    }

    t1.join();
    t2.join();
}

注意這段代碼要開啟代碼優(yōu)化才能觀測到運(yùn)行期指令重排,這里選擇 O2

g++ -o write_x_read_y.out -O2 -pthread -std=c++11 -Wall -Wextra write_x_read_y.cpp

然后使用 jyy 視頻里使用的 Unix 命令進(jìn)行測試并整理結(jié)果

./write_x_read_y.out | head -n | sort | uniq -c

以下結(jié)果是在虛擬機(jī)環(huán)境中執(zhí)行得到的。宿主機(jī) CPU 型號為 AMD Ryzen 7 5800X,OS 為 Windows 10 x64,虛擬機(jī)是 Rocky Linux 8.6。

  0 0 
   0 1 
   1109 1 0 
      2 1 1

成功觀測到“0 0”。假設(shè)程序按照簡單交叉執(zhí)行,執(zhí)行結(jié)果只可能是“0 1”、“1 0”、“1 1”這三種,不可能出現(xiàn)“0 0”。也就是說發(fā)生了運(yùn)行期指令重排。

接下來,將 std::memory_order_relaxed 替換為 std::memory_order_releasestd::memory_order_acquire,再測一遍

x.store(1, std::memory_order_release);    // t1.1
int v = y.load(std::memory_order_acquire); // t1.2
printf("%d ", v);

y.store(1, std::memory_order_release);    // t2.1
int v = x.load(std::memory_order_acquire); // t2.2
printf("%d ", v);

測試結(jié)果為:

  0 0 
  0 1 
   1 0 
      2 1 1

又出現(xiàn)了“0 0”,也就說明這個試?yán)裏o法區(qū)分 relaxed memory model 和 happens-before consistency。這也與理論相符,雖然 t1.1 happens-before t2.2、t2.1 happens-before t1.2,但是卻無法借此推導(dǎo)出約束關(guān)系來限制執(zhí)行結(jié)果。“0 0”依然有可能出現(xiàn)。

接下來替換為 std::memory_order_seq_cst

x.store(1, std::memory_order_seq_cst);    // t1.1
int v = y.load(std::memory_order_seq_cst); // t1.2
printf("%d ", v);

y.store(1, std::memory_order_seq_cst);    // t2.1
int v = x.load(std::memory_order_seq_cst); // t2.2
printf("%d ", v);

測試結(jié)果為:

  0 1 
    151 1 0 
  1 1

這次“0 0”并沒有出現(xiàn),運(yùn)行期指令重排沒有被觀測到。這與理論相符,使用 std::memory_order_seq_cst 的所有原子操作可以視為簡單交叉執(zhí)行,也就是 sequential consistency?!? 0”不可能出現(xiàn)。

write_x_read_y 這個試?yán)芎玫卣f明了 C++ 內(nèi)存模型中的 happens-before consistency 和 sequential consistency 的區(qū)別。它的代碼片段常見于各種相關(guān)文章中,卻沒有完整的代碼和實(shí)際的測試結(jié)果。這下也算補(bǔ)全了 C++ 內(nèi)存模型知識的一塊拼圖。

當(dāng)前標(biāo)題:C++ 內(nèi)存模型 write_x_read_y 試?yán)龢?gòu)造
轉(zhuǎn)載源于:http://chinadenli.net/article22/dsoigjc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站策劃、手機(jī)網(wǎng)站建設(shè)自適應(yīng)網(wǎng)站、定制開發(fā)、關(guān)鍵詞優(yōu)化標(biāo)簽優(yōu)化

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

外貿(mào)網(wǎng)站制作