linux perf工具測試程序cpu cache刷回實驗

一、perf安裝

進入自己編譯的內核,一般目錄是:

/usr/src/linux-x.x.x/tools/perf

 編譯安裝之後,即可使用

make
make install

perf的使用可以查看本文參考文獻1,下面介紹一下perf工具中與cache相關的內容

sudo perf list cache

與cache有關的事件都是Hardware cache event,這類的事件依賴於PMU(performance monitoring unit),一般處理器廠商都會在硬件中加入了 PMU 單元, PMU可以讓我們對某種硬件事件設置counter,一旦發生這種事件,處理器就會統計該事件發生的次數,一旦發生的次數超過設置的counter,便會產生中斷。

可以看到與刷回有關的事件是:LLC-stores

下面結合一個程序,來了解perf對於應用程序cacheline刷回事件的追蹤~

二、測試程序

測試程序結合參考文獻2、3進行編寫,測試程序主要分爲四個小部分:

  1. normal 普通的cpu cache測試程序;
  2. clflush 使用clflush指令刷回cacheline
  3. revise  將數組角標 i,j替換後的cache測試程序
  4. other revise版本使用clflush指令刷回cacheline

完整代碼 test.c : 

#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <x86intrin.h>

int main(int argc, char **argv)
{
        int a[1000][1000];
        if(strcmp(argv[1],"normal") == 0)
        {
                printf("normal \n");
                for(int i = 0; i < 1000; ++i)
                {
                                for(int j = 0; j < 1000; ++j)
                                {
                                                a[i][j] = i + j;
                                }
                }
        }

        else if(strcmp(argv[1],"clflush") == 0)
        { 
                printf("clflush \n");
                for(int i = 0; i < 1000; ++i)
                {
                                for(int j = 0; j < 1000; ++j)
                                {
                                         a[i][j] = i + j;
                                         _mm_clflush(&a[j][i]);
                                }
                }
        }
    
        else if(strcmp(argv[1],"revise") == 0)
        {
                printf("revise \n");
                for(int i = 0; i < 1000; ++i)
                {
                                for(int j = 0; j < 1000; ++j)
                                {
                                                a[j][i] = i + j;
                                }
                }
        }

        else
        {
                printf("other \n");
                for(int i = 0; i < 1000; ++i)
                {
                                for(int j = 0; j < 1000; ++j)
                                {
                                                a[j][i] = i + j;
                                                _mm_clflush(&a[j][i]);
                                }
                }
        }

        return 0;
}

編譯:

gcc test.c -msse2 -o test

運行:

perf stat -e LLC-stores ./test parameter

運行結果:

三、結果分析

1、normal版本,是cache友好型程序,它的刷回最少,運行時間最短

2、clflush版本,按照clflush指令來說,每調用一次clflush指令應該都會對cacheline進行刷回,那麼刷回的次數應該是 1000 * 1000 = 1,000,000次纔對,但是刷回次數卻和normal版本一致,這個原因未知~  在時間消耗上,clflush是normal版本的10倍,說明clflush指令還是有一定的影響。

3、revise版本,對cache不算很友好,LLC-stores是normal的兩倍,由於它緩存不友好,多刷回可以理解,時間是normal版本的兩倍

4、other版本,對cache版本不友好,且每次都刷回,所以刷回次數和時間最長,這個可以理解

存在疑問的地方就是clflush版本,爲什麼刷回次數和normal一致了,可能是perf採樣算法的原因~

四、參考

[1] 《[非易失內存編程] 通過編譯器內置函數 (Intrinsic Functions) 發射 CLFLUSH、CLFLUSHOPT、CLWB、NTSTORE、MFENCE、SFENCE 等指令》https://blog.csdn.net/maokelong95/article/details/81362837

[2] 《系統級性能分析工具perf的介紹與使用》 http://blog.itpub.net/24585765/viewspace-2564885/

[3] 《用linux perf命令來分析程序的cpu cache miss現象》https://blog.csdn.net/stpeace/article/details/80933940

[4] 《Perf 簡介》,這個對perf的利用描述還是挺詳細的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章