1. 程式人生 > >系統技術非業餘研究 » 詳解伺服器記憶體頻寬計算和使用情況測量

系統技術非業餘研究 » 詳解伺服器記憶體頻寬計算和使用情況測量

前段時間我們在MYSQL調優上發現有瓶頸,懷疑是過多拷貝記憶體,導致記憶體頻寬用完。在Linux下CPU的使用情況有top工具, IO裝置的使用情況有iostat工具,就是沒有記憶體使用情況的測量工具。 我們可以看到大量的memcpy和字串拷貝(可以用systemtap來測量),但是像簡單的資料移動操作就無法統計,我們希望在硬體層面有辦法可以查到CPU在過去的一段時間內總共對主存系統發起了多少讀寫位元組數。

所以我們記憶體測量的的目標就歸結為二點:1. 目前我們這樣的伺服器真正的記憶體頻寬是多少。 2. 我們的應用到底佔用了多少頻寬。

首先來看下我們的伺服器配置情況:

$ sudo ~/aspersa/summary 
# Aspersa System Summary Report ##############################
        Date | 2011-09-12 11:23:11 UTC (local TZ: CST +0800)
    Hostname | my031121.sqa.cm4
      Uptime | 13 days,  3:52,  2 users,  load average: 0.02, 0.01, 0.00
      System | Dell Inc.; PowerEdge R710; vNot Specified (<OUT OF SPEC>)
 Service Tag | DHY6S2X
     Release | Red Hat Enterprise Linux Server release 5.4 (Tikanga)
      Kernel | 2.6.18-164.el5
Architecture | CPU = 64-bit, OS = 64-bit
   Threading | NPTL 2.5
    Compiler | GNU CC version 4.1.2 20080704 (Red Hat 4.1.2-44).
     SELinux | Disabled
# Processor ##################################################
  Processors | physical = 2, cores = 12, virtual = 24, hyperthreading = yes
      Speeds | 24x2926.089
      Models | 24xIntel(R) Xeon(R) CPU X5670 @ 2.93GHz
      Caches | 24x12288 KB
# Memory #####################################################
       Total | 94.40G
        Free | 4.39G
        Used | physical = 90.01G, swap = 928.00k, virtual = 90.01G
     Buffers | 1.75G
      Caches | 7.85G
        Used | 78.74G
  Swappiness | vm.swappiness = 0
 DirtyPolicy | vm.dirty_ratio = 40, vm.dirty_background_ratio = 10
  Locator   Size     Speed             Form Factor   Type          Type Detail
  ========= ======== ================= ============= ============= ===========
  DIMM_A1   8192 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  DIMM_A2   8192 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  DIMM_A3   8192 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  DIMM_A4   8192 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  DIMM_A5   8192 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  DIMM_A6   8192 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  DIMM_B1   8192 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  DIMM_B2   8192 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  DIMM_B3   8192 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  DIMM_B4   8192 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  DIMM_B5   8192 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  DIMM_B6   8192 MB  1333 MHz (0.8 ns) DIMM          {OUT OF SPEC} Synchronous
  DIMM_A7   {EMPTY}  Unknown           DIMM          {OUT OF SPEC} Synchronous
  DIMM_A8   {EMPTY}  Unknown           DIMM          {OUT OF SPEC} Synchronous
  DIMM_A9   {EMPTY}  Unknown           DIMM          {OUT OF SPEC} Synchronous
  DIMM_B7   {EMPTY}  Unknown           DIMM          {OUT OF SPEC} Synchronous
  DIMM_B8   {EMPTY}  Unknown           DIMM          {OUT OF SPEC} Synchronous
  DIMM_B9   {EMPTY}  Unknown           DIMM          {OUT OF SPEC} Synchronous
...

DELL R710的機器上有2個X5670CPU,每個上面有6個core,超執行緒,所以共有24個邏輯CPU。上面插了12根 8192MB(1333 MHz)記憶體條。

我們的機器架構從之前的FSB匯流排結構變成現在的numa架構,謝謝@fcicq提供的資訊,請參考下圖(來源):

我們可以清楚的看到每個CPU都有自己的記憶體控制器直接連線到記憶體去,而且有3個通道, CPU直接通過QPI連線。 記憶體控制器和QPI上面都會流動資料。

我們伺服器用的是DDR3記憶體,所以我們需要計算下在這樣的架構下我們記憶體的頻寬。

DDR3記憶體頻寬如何計算,參看 這裡
從配置資訊可以看到我的伺服器的記憶體條: DIMM_A1 8192 MB 1333 MHz (0.8 ns), 有12根,每個CPU連線6根。
根據文章我們計算如下:每個通道 (1333/8)*64*8 /8 = 10.6G Byte;而我們的CPU是3個通道的,也就是說這個CPU的總的記憶體頻寬是 10.6*3=31.8G;我的機器有2個CPU,所以總的通道是63.6G, 理論上是這樣的對吧(有錯,請糾正我),我們等下實際測量下。

從上面的計算,顯然記憶體頻寬不是瓶頸。那問題出在那裡呢,我們繼續看!

我們需要個工具能夠搬動記憶體的工具。這類工具測試處理的頻寬是指在一個執行緒能跑出的最大記憶體頻寬。 挑個簡單的mbw(mbw – Memory BandWidth benchmark)來玩下:

$ sudo apt-get install mbw
$ mbw -q -n 1 256
0	Method: MEMCPY	Elapsed: 0.19652	MiB: 256.00000	Copy: 1302.647 MiB/s
AVG	Method: MEMCPY	Elapsed: 0.19652	MiB: 256.00000	Copy: 1302.647 MiB/s
0	Method: DUMB	Elapsed: 0.12668	MiB: 256.00000	Copy: 2020.840 MiB/s
AVG	Method: DUMB	Elapsed: 0.12668	MiB: 256.00000	Copy: 2020.840 MiB/s
0	Method: MCBLOCK	Elapsed: 0.02945	MiB: 256.00000	Copy: 8693.585 MiB/s
AVG	Method: MCBLOCK	Elapsed: 0.02945	MiB: 256.00000	Copy: 8693.585 MiB/s

CPU記憶體頻寬測量工具方面,在@王王爭 同學大力幫助下,同時給我詳盡地介紹了PTU(intel-performance-tuning-utility),在 這裡 可以下載。
解開下載的二進位制包後,bin裡面帶的vtbwrun就是我們的硬體層面的記憶體頻寬使用測量工具,下面是使用幫助:

$ sudo ptu40_005_lin_intel64/bin/vtbwrun  --help

***********************************
                PTU                                
        Performance Tuning Utility     
                For                
              Nehalem              
              Ver 0.4              
***********************************

Usage: ./ptu [-c] [-i <iterations>] [-A] [-r] [-p] [-w] 
-c disable CPU check.
-i <iterations> specify how many iterations PTU should run.
-A Automated mode, no user Input.
-r Monitor QHL read/write requests from the IOH
*************************** EXCLUSIVE ******************************
-p Monitor partial writes on Memory Channel 0,1,2
-w Monitor WriteBack, Conflict event
*************************** EXCLUSIVE ******************************

$ sudo ptu40_005_lin_intel64/bin/vtbwrun -c -A

執行期截圖如下:

該圖清楚的指出System Memory Throughput(MB/s): 13019.45, 其中QPI也消耗挺大的。

此外,我們還需要知道 CPU的topology結構,也就是說每個作業系統的CPU對應到哪個CPU哪個核心的哪個超執行緒去。有了這個資訊,我們才能用taskset把記憶體測試工具繫結到指定的CPU去,才能精確的觀察記憶體使用情況。CPU topology參看這裡

$ sudo ./cpu_topology64.out 
        Advisory to Users on system topology enumeration

This utility is for demonstration purpose only. It assumes the hardware topology
configuration within a coherent domain does not change during the life of an OS
session. If an OS support advanced features that can change hardware topology 
configurations, more sophisticated adaptation may be necessary to account for 
the hardware configuration change that might have added and reduced the number 
of logical processors being managed by the OS.

User should also`be aware that the system topology enumeration algorithm is 
based on the assumption that CPUID instruction will return raw data reflecting 
the native hardware configuration. When an application runs inside a virtual 
machine hosted by a Virtual Machine Monitor (VMM), any CPUID instructions 
issued by an app (or a guest OS) are trapped by the VMM and it is the VMM's 
responsibility and decision to emulate/supply CPUID return data to the virtual 
machines. When deploying topology enumeration code based on querying CPUID 
inside a VM environment, the user must consult with the VMM vendor on how an VMM 
will emulate CPUID instruction relating to topology enumeration.



        Software visible enumeration in the system: 
Number of logical processors visible to the OS: 24 
Number of logical processors visible to this process: 24 
Number of processor cores visible to this process: 12 
Number of physical packages visible to this process: 2 


        Hierarchical counts by levels of processor topology: 
 # of cores in package  0 visible to this process: 6 .
         # of logical processors in Core 0 visible to this process: 2 .
         # of logical processors in Core  1 visible to this process: 2 .
         # of logical processors in Core  2 visible to this process: 2 .
         # of logical processors in Core  3 visible to this process: 2 .
         # of logical processors in Core  4 visible to this process: 2 .
         # of logical processors in Core  5 visible to this process: 2 .
 # of cores in package  1 visible to this process: 6 .
         # of logical processors in Core 0 visible to this process: 2 .
         # of logical processors in Core  1 visible to this process: 2 .
         # of logical processors in Core  2 visible to this process: 2 .
         # of logical processors in Core  3 visible to this process: 2 .
         # of logical processors in Core  4 visible to this process: 2 .
         # of logical processors in Core  5 visible to this process: 2 .


        Affinity masks per SMT thread, per core, per package: 
Individual:
        P:0, C:0, T:0 --> 1
        P:0, C:0, T:1 --> 1z3

Core-aggregated:
        P:0, C:0 --> 1001
Individual:
        P:0, C:1, T:0 --> 4
        P:0, C:1, T:1 --> 4z3

Core-aggregated:
        P:0, C:1 --> 4004
Individual:
        P:0, C:2, T:0 --> 10
        P:0, C:2, T:1 --> 1z4

Core-aggregated:
        P:0, C:2 --> 10010
Individual:
        P:0, C:3, T:0 --> 40
        P:0, C:3, T:1 --> 4z4

Core-aggregated:
        P:0, C:3 --> 40040
Individual:
        P:0, C:4, T:0 --> 100
        P:0, C:4, T:1 --> 1z5

Core-aggregated:
        P:0, C:4 --> 100100
Individual:
        P:0, C:5, T:0 --> 400
        P:0, C:5, T:1 --> 4z5

Core-aggregated:
        P:0, C:5 --> 400400

Pkg-aggregated:
        P:0 --> 555555
Individual:
        P:1, C:0, T:0 --> 2
        P:1, C:0, T:1 --> 2z3

Core-aggregated:
        P:1, C:0 --> 2002
Individual:
        P:1, C:1, T:0 --> 8
        P:1, C:1, T:1 --> 8z3

Core-aggregated:
        P:1, C:1 --> 8008
Individual:
        P:1, C:2, T:0 --> 20
        P:1, C:2, T:1 --> 2z4

Core-aggregated:
        P:1, C:2 --> 20020
Individual:
        P:1, C:3, T:0 --> 80
        P:1, C:3, T:1 --> 8z4

Core-aggregated:
        P:1, C:3 --> 80080
Individual:
        P:1, C:4, T:0 --> 200
        P:1, C:4, T:1 --> 2z5

Core-aggregated:
        P:1, C:4 --> 200200
Individual:
        P:1, C:5, T:0 --> 800
        P:1, C:5, T:1 --> 8z5

Core-aggregated:
        P:1, C:5 --> 800800

Pkg-aggregated:
        P:1 --> aaaaaa


        APIC ID listings from affinity masks
OS cpu   0, Affinity mask 00000001 - apic id 20
OS cpu   1, Affinity mask 00000002 - apic id 0
OS cpu   2, Affinity mask 00000004 - apic id 22
OS cpu   3, Affinity mask 00000008 - apic id 2
OS cpu   4, Affinity mask 00000010 - apic id 24
OS cpu   5, Affinity mask 00000020 - apic id 4
OS cpu   6, Affinity mask 00000040 - apic id 30
OS cpu   7, Affinity mask 00000080 - apic id 10
OS cpu   8, Affinity mask 00000100 - apic id 32
OS cpu   9, Affinity mask 00000200 - apic id 12
OS cpu  10, Affinity mask 00000400 - apic id 34
OS cpu  11, Affinity mask 00000800 - apic id 14
OS cpu  12, Affinity mask 00001000 - apic id 21
OS cpu  13, Affinity mask 00002000 - apic id 1
OS cpu  14, Affinity mask 00004000 - apic id 23
OS cpu  15, Affinity mask 00008000 - apic id 3
OS cpu  16, Affinity mask 00010000 - apic id 25
OS cpu  17, Affinity mask 00020000 - apic id 5
OS cpu  18, Affinity mask 00040000 - apic id 31
OS cpu  19, Affinity mask 00080000 - apic id 11
OS cpu  20, Affinity mask 00100000 - apic id 33
OS cpu  21, Affinity mask 00200000 - apic id 13
OS cpu  22, Affinity mask 00400000 - apic id 35
OS cpu  23, Affinity mask 00800000 - apic id 15


Package 0 Cache and Thread details


Box Description:
Cache  is cache level designator
Size   is cache size
OScpu# is cpu # as seen by OS
Core   is core#[_thread# if > 1 thread/core] inside socket
AffMsk is AffinityMask(extended hex) for core and thread
CmbMsk is Combined AffinityMask(extended hex) for hw threads sharing cache
       CmbMsk will differ from AffMsk if > 1 hw_thread/cache
Extended Hex replaces trailing zeroes with 'z#'
       where # is number of zeroes (so '8z5' is '0x800000')
L1D is Level 1 Data cache, size(KBytes)= 32,  Cores/cache= 2, Caches/package= 6
L1I is Level 1 Instruction cache, size(KBytes)= 32,  Cores/cache= 2, Caches/package= 6
L2 is Level 2 Unified cache, size(KBytes)= 256,  Cores/cache= 2, Caches/package= 6
L3 is Level 3 Unified cache, size(KBytes)= 12288,  Cores/cache= 12, Caches/package= 1
      +-------------+-------------+-------------+-------------+-------------+-------------+
Cache |   L1D       |   L1D       |   L1D       |   L1D       |   L1D       |   L1D       |
Size  |   32K       |   32K       |   32K       |   32K       |   32K       |   32K       |
OScpu#|     0     12|     2     14|     4     16|     6     18|     8     20|    10     22|
Core  | c0_t0  c0_t1| c1_t0  c1_t1| c2_t0  c2_t1| c3_t0  c3_t1| c4_t0  c4_t1| c5_t0  c5_t1|
AffMsk|     1    1z3|     4    4z3|    10    1z4|    40    4z4|   100    1z5|   400    4z5|
CmbMsk|  1001       |  4004       | 10010       | 40040       |100100       |400400       |
      +-------------+-------------+-------------+-------------+-------------+-------------+

Cache |   L1I       |   L1I       |   L1I       |   L1I       |   L1I       |   L1I       |
Size  |   32K       |   32K       |   32K       |   32K       |   32K       |   32K       |
      +-------------+-------------+-------------+-------------+-------------+-------------+

Cache |    L2       |    L2       |    L2       |    L2       |    L2       |    L2       |
Size  |  256K       |  256K       |  256K       |  256K       |  256K       |  256K       |
      +-------------+-------------+-------------+-------------+-------------+-------------+

Cache |    L3                                                                             |
Size  |   12M                                                                             |
CmbMsk|555555                                                                             |
      +-----------------------------------------------------------------------------------+

Combined socket AffinityMask= 0x555555


Package 1 Cache and Thread details


Box Description:
Cache  is cache level designator
Size   is cache size
OScpu# is cpu # as seen by OS
Core   is core#[_thread# if > 1 thread/core] inside socket
AffMsk is AffinityMask(extended hex) for core and thread
CmbMsk is Combined AffinityMask(extended hex) for hw threads sharing cache
       CmbMsk will differ from AffMsk if > 1 hw_thread/cache
Extended Hex replaces trailing zeroes with 'z#'
       where # is number of zeroes (so '8z5' is '0x800000')
      +-------------+-------------+-------------+-------------+-------------+-------------+
Cache |   L1D       |   L1D       |   L1D       |   L1D       |   L1D       |   L1D       |
Size  |   32K       |   32K       |   32K       |   32K       |   32K       |   32K       |
OScpu#|     1     13|     3     15|     5     17|     7     19|     9     21|    11     23|
Core  | c0_t0  c0_t1| c1_t0  c1_t1| c2_t0  c2_t1| c3_t0  c3_t1| c4_t0  c4_t1| c5_t0  c5_t1|
AffMsk|     2    2z3|     8    8z3|    20    2z4|    80    8z4|   200    2z5|   800    8z5|
CmbMsk|  2002       |  8008       | 20020       | 80080       |200200       |800800       |
      +-------------+-------------+-------------+-------------+-------------+-------------+

Cache |   L1I       |   L1I       |   L1I       |   L1I       |   L1I       |   L1I       |
Size  |   32K       |   32K       |   32K       |   32K       |   32K       |   32K       |
      +-------------+-------------+-------------+-------------+-------------+-------------+

Cache |    L2       |    L2       |    L2       |    L2       |    L2       |    L2       |
Size  |  256K       |  256K       |  256K       |  256K       |  256K       |  256K       |
      +-------------+-------------+-------------+-------------+-------------+-------------+

Cache |    L3                                                                             |
Size  |   12M                                                                             |
CmbMsk|aaaaaa                                                                             |
      +-----------------------------------------------------------------------------------+


#或者最簡單的方法,讓Erlang告訴我們
$ erl
Erlang R14B04 (erts-5.8.5)  [64-bit] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.8.5  (abort with ^G)
1> erlang:system_info(cpu_topology).
[{processor,[{core,[{thread,{logical,1}},
                    {thread,{logical,13}}]},
             {core,[{thread,{logical,3}},{thread,{logical,15}}]},
             {core,[{thread,{logical,5}},{thread,{logical,17}}]},
             {core,[{thread,{logical,7}},{thread,{logical,19}}]},
             {core,[{thread,{logical,9}},{thread,{logical,21}}]},
             {core,[{thread,{logical,11}},{thread,{logical,23}}]}]},
 {processor,[{core,[{thread,{logical,0}},
                    {thread,{logical,12}}]},
             {core,[{thread,{logical,2}},{thread,{logical,14}}]},
             {core,[{thread,{logical,4}},{thread,{logical,16}}]},
             {core,[{thread,{logical,6}},{thread,{logical,18}}]},
             {core,[{thread,{logical,8}},{thread,{logical,20}}]},
             {core,[{thread,{logical,10}},{thread,{logical,22}}]}]}]

#我們順手寫個shell指令碼可以執行多個mbw繫結在指定的CPU上
$ cat run_mbw.sh
#!/bin/bash
for i in $(seq $1 $3 $2)
do
    echo $i
    taskset -c $i mbw -q -n 9999 256 >/dev/null &
done

$ chmod +x run_mbw.sh 

我們知道CPU0的邏輯CPU號碼是奇數, CPU1的邏輯CPU號碼是偶數.
只要執行 ./run_mbw from to increase 就達到目的.

有了這些工具,我們就可以做試驗了,喝口水繼續:

$ sudo ./run_mbw.sh  0 22 2
0
2
...

我們可以看到CPU的繫結情況,符合預期,見下圖:

那麼記憶體的頻寬呢?看圖:

有點問題,記憶體被2個CPU消耗,並且有QPI。

$ sudo./run_mbw.sh  1 23 2
1
3
...

見下圖

這時候所有的CPU已經跑滿,那麼記憶體的頻寬呢?看圖:

我們看出這臺機器記憶體最大頻寬32G。

我們很奇怪呀,為什麼會出現這種情況呢?CPU並沒有按照預期消耗自己的那部分記憶體,而且QPI的消耗也很大。
究根本原因是我們在作業系統啟動的時候把numa給關掉了,避免mysqld在大記憶體的情況下引起swap.
我們來確認下:

# cat /proc/cmdline 
ro root=LABEL=/ numa=off  console=tty0 console=ttyS1,115200 

找到原因就好辦了。沒關係,我們重新找臺沒有關numa的機器,實驗如下:

$ cat /proc/cmdline 
ro root=LABEL=/ console=tty0 console=ttyS0,9600 #確實沒關numa, 現在機器有2個node

$ sudo ~/aspersa/summary 
# Aspersa System Summary Report ##############################
        Date | 2011-09-12 12:26:18 UTC (local TZ: CST +0800)
    Hostname | my031089
      Uptime | 18 days, 10:33,  2 users,  load average: 0.04, 0.01, 0.00
      System | Huawei Technologies Co., Ltd.; Tecal RH2285; vV100R001 (Main Server Chassis)
 Service Tag | 210231771610B4001897
     Release | Red Hat Enterprise Linux Server release 5.4 (Tikanga)
      Kernel | 2.6.18-164.el5
Architecture | CPU = 64-bit, OS = 64-bit
   Threading | NPTL 2.5
    Compiler | GNU CC version 4.1.2 20080704 (Red Hat 4.1.2-44).
     SELinux | Disabled
# Processor ##################################################
  Processors | physical = 2, cores = 8, virtual = 16, hyperthreading = yes
      Speeds | 16x1600.000
      Models | 16xIntel(R) Xeon(R) CPU E5620 @ 2.40GHz
      Caches | 16x12288 KB
# Memory #####################################################
       Total | 23.53G
        Free | 8.40G
        Used | physical = 15.13G, swap = 20.12M, virtual = 15.15G
     Buffers | 863.79M
      Caches | 4.87G
        Used | 8.70G
  Swappiness | vm.swappiness = 60
 DirtyPolicy | vm.dirty_ratio = 40, vm.dirty_background_ratio = 10
  Locator   Size     Speed             Form Factor   Type          Type Detail
  ========= ======== ================= ============= ============= ===========
  DIMM_A0   4096 MB  1066 MHz (0.9 ns) DIMM          {OUT OF SPEC} Other   
  DIMM_B0   4096 MB  1066 MHz (0.9 ns) DIMM          {OUT OF SPEC} Other   
  DIMM_C0   4096 MB  1066 MHz (0.9 ns) DIMM          {OUT OF SPEC} Other   
  DIMM_D0   4096 MB  1066 MHz (0.9 ns) DIMM          {OUT OF SPEC} Other   
  DIMM_E0   4096 MB  1066 MHz (0.9 ns) DIMM          {OUT OF SPEC} Other   
  DIMM_F0   4096 MB  1066 MHz (0.9 ns) DIMM          {OUT OF SPEC} Other   
  DIMM_A1   {EMPTY}  Unknown           DIMM          {OUT OF SPEC} Other   
  DIMM_B1   {EMPTY}  Unknown           DIMM          {OUT OF SPEC} Other   
  DIMM_C1   {EMPTY}  Unknown           DIMM          {OUT OF SPEC} Other   
  DIMM_D1   {EMPTY}  Unknown           DIMM          {OUT OF SPEC} Other   
  DIMM_E1   {EMPTY}  Unknown           DIMM          {OUT OF SPEC} Other   
  DIMM_F1   {EMPTY}  Unknown           DIMM          {OUT OF SPEC} Other   
...

$ erl
Erlang R14B03 (erts-5.8.4)  [64-bit] [smp:16:16] [rq:16] [async-threads:0] [hipe] [kernel-poll:false]

Eshell V5.8.4  (abort with ^G)
1>  erlang:system_info(cpu_topology).
erlang:system_info(cpu_topology).
[{node,[{processor,[{core,[{thread,{logical,4}},
                           {thread,{logical,12}}]},
                    {core,[{thread,{logical,5}},{thread,{logical,13}}]},
                    {core,[{thread,{logical,6}},{thread,{logical,14}}]},
                    {core,[{thread,{logical,7}},{thread,{logical,15}}]}]}]},
 {node,[{processor,[{core,[{thread,{logical,0}},
                           {thread,{logical,8}}]},
                    {core,[{thread,{logical,1}},{thread,{logical,9}}]},
                    {core,[{thread,{logical,2}},{thread,{logical,10}}]},
                    {core,[{thread,{logical,3}},{thread,{logical,11}}]}]}]}]
2> 

這是一臺有2個E5620 CPU的華為生產的機器,總共16個邏輯CPU,其中邏輯CPU4-7,12-15對應於物理CPU0, 邏輯CPU0-3,8-11對應於物理CPU1。

$ ./run_mbw.sh 4 5 1
4
5

這時候的記憶體頻寬圖:
從圖中我們可以看出2個mbw繫結在CPU 0上消耗了10.4G頻寬,CPU1無消耗,QPI無消耗,符合預期。

繼續加大壓力:

$ ./run_mbw.sh 6 7 1
6
7


記憶體消耗達到16G了,繼續加壓力。

$ ./run_mbw.sh 12 15 1
12
13
14
15


我們看到執行緒數目加大,但是記憶體頻寬保持不變,說明已經到瓶頸了。該CPU瓶頸16G。

我們在另外一個CPU1上實驗下:

$ ./run_mbw.sh 0 3 1
0
1
2
3
$ ./run_mbw.sh 8 11 1
8
9
10
11

一下子把壓力全加上去,看截圖:

從圖中我們可以看出CPU0,CPU1都消耗差不多15G的頻寬,總頻寬達到30G。

到此我們很明白我們如何計算我們的伺服器頻寬,以及如何測量目前的頻寬使用情況,是不是很有意思?
非常感謝網際網路讓我們解決問題這麼迅速。

BTW:測量出來的頻寬和理論差距一倍,是不是我哪裡計算錯了,請大俠們幫我解惑,謝謝!

後記: 在華為的機器上記憶體是1066MHZ的,理論上的每通道頻寬是 1066*8=8.52G,每個CPU有25.56G, 從截圖中可以看到CPU0的頻寬達到17.17G,那麼已經達到理論峰值的67.2%. 側面驗證了DDR的頻寬演算法是正確的,再次謝謝@王王爭 同學。

祝玩得開心!

Post Footer automatically generated by wp-posturl plugin for wordpress.

相關推薦

系統技術業餘研究 » 伺服器記憶體頻寬計算使用情況測量

前段時間我們在MYSQL調優上發現有瓶頸,懷疑是過多拷貝記憶體,導致記憶體頻寬用完。在Linux下CPU的使用情況有top工具, IO裝置的使用情況有iostat工具,就是沒有記憶體使用情況的測量工具。 我們可以看到大量的memcpy和字串拷貝(可以用systemtap來測量),但是像簡單的資料移

系統技術業餘研究 » Erlang R15的記憶體delayed dealloc特性對訊息密集型程式的影響

在新的NUMA體系結構下,每個CPU都有自己的本地記憶體,如果要訪問其他CPU的記憶體,那算remote了,要走CPU之間的QPI通道,通常這樣速度會有40%的下降。 那麼對於多執行緒的程式來講,這個硬體的變化對軟體也有很大的影響。在多執行緒程式裡面,通常一個執行緒會為一個物件分配記憶體,然後把這

系統技術業餘研究 » Fio模擬Mysql伺服器IO壓力指令碼

fio是個非常好用的io壓力模擬工具,功能非常齊全, 有興趣的同學參看 這裡。 這裡我用fio模擬我們線上mysql伺服器的壓力來為廠家送來的pci-ssd卡做壓力測試,底下是指令碼(已經測試正確),也許有的同學有用。 $ cat mysql-test # QPS: 40000(10 core

系統技術業餘研究 » Erlang 網路密集型伺服器的瓶頸解決思路

最近我們的Erlang IO密集型的伺服器程式要做細緻的效能提升,從每秒40萬包處理提升到60萬目標,需要對程序和IO排程器的原理很熟悉,並且對行為進行微調,花了不少時間參閱了相關的文件和程式碼。 其中最有價值的二篇文章是: 1. Characterizing the Scalability of

系統技術業餘研究 » gen_tcp:send的深度使用指南(初稿)

在大家的印象中, gen_tcp:send是個很樸素的函式, 一呼叫資料就喀嚓喀嚓到了對端. 這是個很大的誤解, Erlang的otp文件寫的很不清楚. 而且這個功能對於大部分的網路程式是至關重要的, 它的使用對否極大了影響了應用的效能. 我聽到很多同學在抱怨erlang的效能低或者出了很奇怪的問

系統技術業餘研究 » ECUG2010分享:C1000K高效能伺服器構架技術

點選這裡下載 ppt 視訊這裡 照片這裡 這次ECUG2010的講師來自不同的國家,有點國際化的味道,也說明了這個世界越來越扁平,技術越越來越同步,我們追隨技術的壓力也越來越大。 Post Footer automatically generated by wp-posturl plugin

系統技術業餘研究 » 最快的Erlang http hello world 伺服器調優指南 (20Khttp短連結請求/S每桌面CPU)

erl的虛擬機器有2種方式 plain版本的和smp版本的。 smp版本由於鎖的開銷相比要比plain版本的慢很多。而32位機器由於記憶體訪問比64位的少,也會快出很多。所有我選擇在32位的linux系統下調優這個httpd伺服器。這個伺服器就是實現個簡單的功能,在browser下返回hello

系統技術業餘研究 » Tsung用於壓測MySQL伺服器的指令碼

這個MySQL伺服器壓測的需求是 : 環境: Linux RHEL 5U4 X86-64, 24G記憶體, 16核. MySQL伺服器在xx.232.36.1上。 壓力由最多32個客戶端發起,每個客戶端分別做update, insert, delete操作,概率分別是50%, 30%, 20%

系統技術業餘研究 » 調查伺服器響應時間的利器 tcprstat

我們在做伺服器程式的時候,經常要知道一個請求的響應時間,藉以優化或者定位問題。 通常的做法是在程式碼裡面加入日誌計算時間,這個方法有問題,時間不準確。因為資料從網絡卡到應用程式,從應用到網絡卡的時間沒有被計算在內。 而且這個時間隨著系統的負載有很大的變化。 那同學說,我wireshark, tcp

系統技術業餘研究 » Erlang版TCP伺服器對抗攻擊解決方案

網際網路上的TCP伺服器面對的環境情況比企業私有的伺服器要複雜很多。常見的針對tcp伺服器的攻擊有以下幾種: 1. 偽造協議,導致伺服器crash. 比如說某條命令的欄位長度,協議最大規定是1024,偽造個4096的。 2. 偽造大的報文,比如說一個包有1024M這麼大。 3. 消耗伺服器資源。開

系統技術業餘研究 » 簡易的python web伺服器用途

我們在工作中經常會需要看下報表,如tsung的統計報表或者lcov的覆蓋情況,這些報表通常為了方便都會作成html格式的。我們可以把這些html網頁打包拉回去用瀏覽器慢慢看,但是每次都要打包,拉資料非常麻煩。我們可以架設個web伺服器來做這個事情。 apache或者nginx都太龐大,設定起來太麻

系統技術業餘研究

ItPub寫的文章“2017 年度 DB-Engines 資料庫冠軍得主:PostgreSQL 封王!”, 點選 這裡 進一步閱讀 升的最快的幾個資料庫,我簡單的無責任點評: PG資料庫是很老的資料庫,不過這幾年冉冉升起,因為是學院派的,有很好的學術和智力的支援,一直以來在資料庫的體系結構,程式碼

系統技術業餘研究 » MySQL資料庫架構的演化觀察

MySQL資料庫架構的演化觀察 December 14th, 2017 Categories: 資料庫 Tags: mysql

系統技術業餘研究 » inet_dist_connect_options

Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke

系統技術業餘研究 » 推薦工作機會

最後更新時間:2014/11/28 請賜簡歷至:[email protected], 感謝您對加入我們公司有興趣,我們希望能早日和您共事。 以下幾個職位1年內有效,歡迎內部轉崗:
 資深資料工程師 公司:阿里(核心系統資料庫組) 工作地點:杭州(西溪園區) 崗位描述: 分析雲服務產生的海

系統技術業餘研究 » 新的工作研究方向

和大家更新下: 做了將近8年資料庫後,我的工作和研究方向將會延伸到虛擬化和計算相關的雲服務,希望能夠和大家一起進步,Happy New Year! 預祝大家玩得開心! Post Footer automatically generated by wp-posturl plugin for w

系統技術業餘研究 » 叢集引入inet_dist_{listen,connect}_options更精細引數微調

Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke

系統技術業餘研究 » 2017升的最快的幾個資料庫無責任點評

ItPub寫的文章“2017 年度 DB-Engines 資料庫冠軍得主:PostgreSQL 封王!”, 點選 這裡 進一步閱讀 升的最快的幾個資料庫,我簡單的無責任點評: PG資料庫是很老的資料庫,不過這幾年冉冉升起,因為是學院派的,有很好的學術和智力的支援,一直以來在資料庫的體系結構,程式碼

系統技術業餘研究 » Erlang 17.5引入+hpds命令列控制程序預設字典大小

Erlang 17.5釋出引入控制程序預設字典大小的命令列引數: Erlang/OTP 17.5 has been released Written by Henrik, 01 Apr 2015 Some highlights of the release are: ERTS: Added co

系統技術業餘研究 » inet_dist_listen_options

Erlang 17.5版本引入了inet_dist_{listen,connect}_options,對於結點間的互聯socket可以有更精細的控制,RPC的時候效能可以微調: raimo/inet_tcp_dist-priority-option/OTP-12476: Document ke