搜尋
首頁後端開發C++了解並解決多線程應用程式中的錯誤共享以及我遇到的實際問題

Understanding and Solving False Sharing in Multi-threaded Applications with an actual issue I had

最近,我正在研究計算泊松分佈(amath_pdist)的函數的多執行緒實作。目標是將工作負載分配到多個執行緒以提高效能,特別是對於大型陣列。然而,我注意到隨著數組大小的增加,速度明顯減慢,而不是達到預期的加速。

經過一番調查,我發現了罪魁禍首:虛假分享。在這篇文章中,我將解釋什麼是錯誤共享,展示導致問題的原始程式碼,並分享導致效能大幅提升的修復方法。


問題:多執行緒程式碼中的錯誤共享

錯誤共享當多個執行緒在共享陣列的不同部分工作時發生,但它們的資料駐留在同一個快取行中。高速緩存行是記憶體和 CPU 快取之間傳輸的最小資料單元(通常為 64 位元組)。如果一個執行緒寫入快取行的一部分,就會使其他執行緒的該行無效,即使它們正在處理邏輯上獨立的資料。由於重複重新載入快取行,這種不必要的失效會導致效能顯著下降。

這是我的原始程式碼的簡化版本:

void *calculate_pdist_segment(void *data) {
    struct pdist_segment *segment = (struct pdist_segment *)data;
    size_t interval_a = segment->interval_a, interval_b = segment->interval_b;
    double lambda = segment->lambda;
    int *d = segment->data;

    for (size_t i = interval_a; i pdist[i] = pow(lambda, d[i]) * exp(-lambda) / tgamma(d[i] + 1);
    }
    return NULL;
}

double *amath_pdist(int *data, double lambda, size_t n_elements, size_t n_threads) {
    double *pdist = malloc(sizeof(double) * n_elements);
    pthread_t threads[n_threads];
    struct pdist_segment segments[n_threads];
    size_t step = n_elements / n_threads;

    for (size_t i = 0; i 




<hr>

<h3>
  
  
  問題發生在哪裡
</h3>

<p>上面的程式碼中:</p>

  • 陣列 pdist 在所有執行緒之間共用。
  • 每個執行緒寫入特定範圍的索引(interval_a 到interval_b)。
  • 在段邊界,相鄰索引可能駐留在同一快取行中。例如,如果 pdist[249999] 和 pdist[250000] 共用一個快取行,則執行緒 1(處理 pdist[249999])和執行緒 2(處理 pdist[250000])會使彼此的快取行無效。

這個問題對於較大的陣列來說擴充性很差。雖然邊界問題看起來很小,但迭代的絕對數量放大了快取失效的成本,導致數秒鐘的不必要的開銷。


解決方案:將記憶體與快取行邊界對齊

為了解決這個問題,我使用 posix_memalign 來確保 pdist 陣列與 64 位元組邊界 對齊。這保證了執行緒在完全獨立的快取行上運行,消除了錯誤共享。

這是更新後的程式碼:

double *amath_pdist(int *data, double lambda, size_t n_elements, size_t n_threads) {
    double *pdist;
    if (posix_memalign((void **)&pdist, 64, sizeof(double) * n_elements) != 0) {
        perror("Failed to allocate aligned memory");
        return NULL;
    }

    pthread_t threads[n_threads];
    struct pdist_segment segments[n_threads];
    size_t step = n_elements / n_threads;

    for (size_t i = 0; i 




<hr>

<h3>
  
  
  為什麼這有效?
</h3>

<ol>
<li>
<p><strong>對齊記憶體</strong>:</p>

<ul>
<li>使用 posix_memalign,陣列從快取行邊界開始。 </li>
<li>每個執行緒的分配範圍與快取行整齊對齊,防止重疊。 </li>
</ul>
</li>
<li>
<p><strong>無快取線共享</strong>:</p>
<ul>
<li>執行緒在不同的快取行上運行,消除了錯誤共享導致的失效。 </li>
</ul>
</li>
<li>
<p><strong>提高快取效率</strong>:</p>

<ul>
<li>順序記憶體存取模式與 CPU 預取器很好地配合,進一步提高效能。 </li>
</ul>
</li>
</ol>


<hr>

<h3>
  
  
  結果和要點
</h3>

<p>應用修復後,amath_pdist 函數的運行時間顯著下降。對於我正在測試的資料集,掛鐘時間從 <strong>10.92 秒下降到 0.06 秒</strong>。 </p>

<h4>
  
  
  主要經驗教訓:
</h4>

<ol>
<li>
<strong>錯誤共享</strong>是多執行緒應用程式中一個微妙但關鍵的問題。即使段邊界處的微小重疊也會降低性能。 </li>
<li>
<strong>記憶體對齊</strong>使用posix_memalign是解決錯誤共享的簡單有效的方法。將記憶體與快取行邊界對齊可確保執行緒獨立運行。 </li>
<li>在處理大型陣列或平行處理時,始終分析程式碼是否有與快取相關的問題。 perf 或 valgrind 等工具可以幫助找出瓶頸。 </li>
</ol>

<p>感謝您的閱讀! </p>

<p>對於任何對程式碼感興趣的人,您可以在這裡找到它</p>


          

            
        

以上是了解並解決多線程應用程式中的錯誤共享以及我遇到的實際問題的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
揭穿神話:C真的是一種死語嗎?揭穿神話:C真的是一種死語嗎?May 05, 2025 am 12:11 AM

C 沒有死,反而在許多關鍵領域蓬勃發展:1)遊戲開發,2)系統編程,3)高性能計算,4)瀏覽器和網絡應用,C 依然是主流選擇,展現了其強大的生命力和應用場景。

C#vs. C:編程語言的比較分析C#vs. C:編程語言的比較分析May 04, 2025 am 12:03 AM

C#和C 的主要區別在於語法、內存管理和性能:1)C#語法現代,支持lambda和LINQ,C 保留C特性並支持模板。 2)C#自動內存管理,C 需要手動管理。 3)C 性能優於C#,但C#性能也在優化中。

用C構建XML應用程序:實例用C構建XML應用程序:實例May 03, 2025 am 12:16 AM

在C 中處理XML數據可以使用TinyXML、Pugixml或libxml2庫。 1)解析XML文件:使用DOM或SAX方法,DOM適合小文件,SAX適合大文件。 2)生成XML文件:將數據結構轉換為XML格式並寫入文件。通過這些步驟,可以有效地管理和操作XML數據。

C中的XML:處理複雜的數據結構C中的XML:處理複雜的數據結構May 02, 2025 am 12:04 AM

在C 中處理XML數據結構可以使用TinyXML或pugixml庫。 1)使用pugixml庫解析和生成XML文件。 2)處理複雜的嵌套XML元素,如書籍信息。 3)優化XML處理代碼,建議使用高效庫和流式解析。通過這些步驟,可以高效處理XML數據。

C和性能:它仍然主導C和性能:它仍然主導May 01, 2025 am 12:14 AM

C 在性能優化方面仍然佔據主導地位,因為其低級內存管理和高效執行能力使其在遊戲開發、金融交易系統和嵌入式系統中不可或缺。具體表現為:1)在遊戲開發中,C 的低級內存管理和高效執行能力使得它成為遊戲引擎開發的首選語言;2)在金融交易系統中,C 的性能優勢確保了極低的延遲和高吞吐量;3)在嵌入式系統中,C 的低級內存管理和高效執行能力使得它在資源有限的環境中非常受歡迎。

C XML框架:為您選擇合適的一個C XML框架:為您選擇合適的一個Apr 30, 2025 am 12:01 AM

C XML框架的選擇應基於項目需求。 1)TinyXML適合資源受限環境,2)pugixml適用於高性能需求,3)Xerces-C 支持複雜的XMLSchema驗證,選擇時需考慮性能、易用性和許可證。

C#vs. C:為您的項目選擇正確的語言C#vs. C:為您的項目選擇正確的語言Apr 29, 2025 am 12:51 AM

C#适合需要开发效率和类型安全的项目,而C 适合需要高性能和硬件控制的项目。1)C#提供垃圾回收和LINQ,适用于企业应用和Windows开发。2)C 以高性能和底层控制著称,广泛用于游戏和系统编程。

c  怎麼進行代碼優化c 怎麼進行代碼優化Apr 28, 2025 pm 10:27 PM

C 代碼優化可以通過以下策略實現:1.手動管理內存以優化使用;2.編寫符合編譯器優化規則的代碼;3.選擇合適的算法和數據結構;4.使用內聯函數減少調用開銷;5.應用模板元編程在編譯時優化;6.避免不必要的拷貝,使用移動語義和引用參數;7.正確使用const幫助編譯器優化;8.選擇合適的數據結構,如std::vector。

See all articles

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

這個專案正在遷移到osdn.net/projects/mingw的過程中,你可以繼續在那裡關注我們。 MinGW:GNU編譯器集合(GCC)的本機Windows移植版本,可自由分發的導入函式庫和用於建置本機Windows應用程式的頭檔;包括對MSVC執行時間的擴展,以支援C99功能。 MinGW的所有軟體都可以在64位元Windows平台上運作。

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

Dreamweaver Mac版

Dreamweaver Mac版

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

SublimeText3 英文版

SublimeText3 英文版

推薦:為Win版本,支援程式碼提示!