檔案共享對多執行緒系統效能的影響
大家好,我是 Karan。本次講解的主題是檔案共享及其對多執行緒系統效能的影響。讓我們開始今天的討論。
結構體資料與執行緒操作
為了更好地理解,我建立一個結構體資料,其中包含兩個變數:整數 d1
和整數 d2
。 假設在此架構中,整數的大小為 4 位元組。因此,d1
佔用 4 位元組,d2
也佔用 4 位元組。 假設我的系統有兩個執行緒 t1
和 t2
。
t1
執行緒將對 d1
執行操作。假設資料的一個實例是 d
,其中 d.d1
等於 10,d.d2
等於 20。t1
將對 d.d1
執行操作。同時,t2
執行緒將對 d.d2
執行相同的操作。 假設一個操作需要 x 毫秒,因為這兩個操作是並行的,所以整個操作將在 x 毫秒內完成。
快取行與偽共享
但由於偽共享 (False Sharing),t1
和 t2
雖然在完全獨立的資料上工作,但操作無法同時進行。讓我們試著了解原因。
當我們建立資料的實例時,假設這是我的快取行,大小為 64 位元組(0 到 63)。第二個快取行從 64 到 127。 以這種方式,我的記憶體將在系統中可見。 現在假設 d1
的記憶體分配在這裡 (10)。因為 d2
屬於同一個結構體,所以在 d1
之後,d2
也會被分配記憶體。 在這種情況下,d2
將在這裡。這部分空間可能為空。
現在會發生什麼? 當 t1
執行緒對 d1
執行操作時,它將從記憶體中獲取整個快取行。一旦 d1
獲取了整個快取行,t1
就成為整個快取行的所有者。
偽共享的影響
現在會發生什麼? 當 t2
嘗試存取 d.d2
時,因為整個快取行已被 t1
失效,所以 t2
無法存取 d2
。 因此,即使 d2
是一個獨立的變數,t2
仍然無法存取 d2
,因為整個快取行歸 t1
所有。 在 t1
完成其操作並釋放整個快取行之前,t2
將無法存取變數 d2
。
因此,由於這種情況,首先 t1
將完成其操作,這將花費 x 毫秒。 然後 t2
將完成其操作,總共需要 2x 毫秒。 理想情況下,我們認為系統可以同時在 t1
和 t2
上執行操作,總執行時間應該是 x 毫秒。 但由於偽共享,我的資料以這樣的方式分配,d1
和 d2
位於同一個快取行上。
偽共享的根本原因
當 t1
存取 d1
時,整個快取行被失效。 因此,t2
無法存取整個快取行或無法存取 d2
。 因為如果 d2
必須存取,則必須存取此快取行,而此快取行的存取權現在歸 t1
所有。 這就是所謂的偽共享。 意思是,即使這兩個變數是獨立的,但它們在內部仍然不是獨立的,因為它們在記憶體中的對齊方式使得它們在同一個快取行中獲得記憶體。 因此,t1
和 t2
無法同時存取這兩個變數。
如何避免偽共享
為了避免這種情況,理想情況下應該怎麼做? 我們應該確保 d1
和 d2
位於不同的快取行中。 也就是說,d1
記憶體在快取行 1 中,而 d2
的記憶體在快取行 2 中。 現在會發生什麼? 如果記憶體位於不同的快取行中,當 t1
嘗試存取 d1
(其記憶體在快取行 1 中)時,它現在使整個快取行失效,並且所有權歸 t1
所有。 現在,當 t2
嘗試存取 d2
時,因為此快取行與 d1
的快取行完全不同,所以 t2
將能夠存取 d2
,因為分配給 d2
的記憶體位於完全不同的新快取行中。
t1
將使整個快取行失效,而 t2
將使另一個快取行失效。 但由於這兩個變數位於不同的快取行中,因此可以同時執行這兩個操作。 因此,我們可以在一秒鐘內同時執行任務。
偽共享導致的效能問題
由於偽共享,即使感覺操作在同時進行,但由於系統中的偽共享,d1
和 d2
上的操作將無法同時進行。 因此,雖然我們的系統是多執行緒的,但它的執行速度仍然會非常慢。 這將導致整個系統的效能非常慢。
在下一次課程中,我們將討論如何避免這種偽共享,以便 d1
和 d2
在完全不同的快取行中獲得記憶體。 存在許多方法,我們將嘗試了解所有這些方法的工作原理。 謝謝大家。