簡體   English   中英

rdtsc代碼顯示內存特性(如TLB未命中)對性能的影響

[英]rdtsc code that shows performance impacts from memory characterstics such as TLB miss

我試圖了解rdtsc(),並從http://www.mcs.anl.gov/~kazutomo/rdtsc.html遇到了以下代碼。解釋該代碼的文字為“下一個簡短的基准代碼可能會向您顯示內存特性會影響性能,例如TLB未命中,頁面錯誤或頁面交換進/出。”問題是,我不太了解內存特性如何顯示性能。老實說,我沒有任何線索。如果有人可以解釋一下這將是很棒的。

#include <stdio.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>

#include "rdtsc.h"

#define N (1024*1024*2)

int main(int argc, char* argv[])
{
  unsigned long long a,b;
  unsigned long long min,max;
  char* p;
  int i;

  p = (char*)malloc(N);
  assert( p!=(char*)0 );

  max = 0;
  min = UINT64_MAX;

  for(i=0; i<N; i++ ) {
    a = rdtsc();
    p[i] = 0;
    b = rdtsc() - a;
    if( b > max ) max = b;
    else if( b < min ) min = b;
  }
  printf("min=%llu\n", min);
  printf("max=%llu\n", max);
  return 0;
}

這段代碼只是循環通過2MB緩沖區,向其每個字節寫入0 ,並計算執行每次寫入所花費的時間,更新顯示最短和最長時間的高低水位標記( minmax )。進行每次寫入所需。

假設該程序是在CPU上運行的唯一程序,並且假設它在運行時沒有發生任何異步事件(硬件中斷或計時器中斷),則該程序將向您顯示進行字節寬寫入內存的標稱時間以及處理TLB丟失異常和/或頁面錯誤異常所需的最長時間。

TLB未命中異常是內核在程序嘗試訪問MMU中沒有TLB條目的內存時采用的異常。 MMU是Core Avenue和Memory Lane交叉路口的警務人員,負責將交通引導至應該去的地方。 好,這是一個可怕的比喻。 MMU(內存管理單元)具有兩個主要目的:1)將虛擬內存訪問路由到適當的物理內存地址,以及2)強制執行只讀,讀寫,讀取執行,僅執行等特權,以便對具有沖突屬性的虛擬內存區域(或對未映射的虛擬內存區域)的雜散指針訪問將被捕獲並引發內存訪問異常(例如Linux上的SIGSEGV)。 TLB條目是MMU中的一組硬件寄存器,用於告知MMU虛擬內存頁面或當前加載到物理內存中的頁面組的權限。 但是,MMU沒有無限數量的TLB條目。 它幾乎沒有足夠的TLB條目來描述所有內存頁面的屬性。 因此,如果您嘗試從流程的地址空間訪問沒有當前TLB條目描述其所在頁面的合法地址,則會遇到TLB未命中的情況。 然后,TLB遺漏異常處理程序會從主內存中獲取正確的TLB條目數據,並將其寫入MMU中的TLB條目中; MMU甚至可能具有一些內置機制,用於告知TLB未命中異常處理程序應使用哪個TLB條目...可能是最近最少使用的條目,這是在不久的將來最可能不再需要的條目。

頁面錯誤類似於TLB未命中異常,不同之處在於在這種情況下,該虛擬內存頁面的內容甚至不在物理內存中……它可能根本不存在(新映射的內存頁面),或者它可能先前已換出到磁盤上,以便在有限的物理內存中為程序有時需要的另一頁虛擬內存騰出空間。 盡管TLB未命中異常通常非常快(但是仍然會影響性能),但是由於必須從磁盤(甚至從SSD!)中拉出頁面,因此頁面錯誤異常可能會對性能造成巨大影響。比內存訪問慢一個數量級(或更糟!)。 因此,為了讓CPU忙於處理有用的事情 ,操作系統的頁面錯誤異常處理程序通常會導致當前正在運行的進程換出以支持運行其他進程(處於“就緒”狀態的進程),在磁盤上等待接收數據以填滿請求的虛擬內存頁面。

現在,回到此“測試代碼”及其結果的有效性:

此測試取決於OS + runtime在對malloc(N)的調用中未預分配內存頁面。 我相信這可能是典型的行為; 即使運行時分配了這么多的內存並知道其分配的地址范圍,但操作系統通常不會分配該內存的實際頁面,直到您的程序實際訪問(讀取或寫入)給定頁面中的地址為止。 在許多平台上,頁面的大小為4KB,但也可能更大,例如,較新的Intel Pentium衍生產品的頁面大小為4MB。

因此,假設平台的頁面大小為4KB(4096字節),當您的程序遍歷2MB分配的空間,一次向其寫入0字節時,它將遍歷這4KB頁面中的1024個。 因此,這些寫入中的4193280應該“盡可能快地”發生(不觸發TLB丟失或頁面錯誤異常)。 並且其中多達1024個將觸發TLB丟失和/或頁面錯誤異常。 因此,鑒於寫入的地址位於已加載的虛擬內存頁面中並且其TLB條目當前位於MMU中,因此“最小”時間為執行寫入提供了最快的時間。 “最大”時間為執行寫操作提供了最壞的可能時間,大概是寫給尚未映射到物理內存中的頁面上的地址(並觸發了頁面錯誤異常,也可能觸發了TLB未命中異常)。

如果我們依靠其測試結果來揭示底層硬件的某些特性,則此測試有兩個問題:1)就其本身而言,此代碼忽略了進程交換和/或由於其他原因(例如時間)導致的硬件中斷的影響-切片和網絡數據包“在后台”被接收和處理(這可能會中斷正在運行的進程)。 而且... 2)2MB的測試緩沖區甚至不及新型Intel處理器的MMU的4MB頁面大小。 我不知道什么條件決定操作系統選擇使用4KB頁面還是4MB頁面,因此這可能對您的系統造成影響。 請注意,如果您的minmax彼此處於相同的數量級,則可能是您使用的系統具有4MB頁面,並且如果您的minmax相差一個數量級或更多,則差異可能不能完全歸因於TLB未命中和頁面錯誤異常。 也許這就是為什么作者在聲明中對代碼“ 可能會向您顯示一些性能影響...”稍加掩飾的原因(加了強調)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM