偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

超線程Smt究竟可以快多少?(斐波那契版)

商務辦公
SMT測試很有意思,但是編譯內(nèi)核涉及的因素太多了,包括訪問文件系統(tǒng)等耗時受到存儲器性能的影響,難以估算,因此很難評判SMT對性能的提升如何。

[[430416]]

宋老師的SMT測試很有意思,但是編譯內(nèi)核涉及的因素太多了,包括訪問文件系統(tǒng)等耗時受到存儲器性能的影響,難以估算,因此很難評判SMT對性能的提升如何。

為了探究SMT對計算密集型workload的效果,我自己寫了一個簡單的測試程序。

使用pthread開多個線程,每個線程分別計算斐波那契數(shù)列第N號元素的值。每個線程計算斐波那契數(shù)列時除線程的元數(shù)據(jù)外只分配兩個unsigned long變量,由此避免過高的內(nèi)存開銷。

workload的詳細代碼和測試腳本在[https://github.com/HongweiQin/smt_test]

毫無疑問,這是一個計算密集型負載,我在自己的筆記本上運行,配置如下(省略了一些不重要的項目):

  1. $ lscpu 
  2. Architecture:                    x86_64 
  3. CPU(s):                          12 
  4. On-line CPU(s) list:             0-11 
  5. Thread(s) per core:              2 
  6. Core(s) per socket:              6 
  7. Socket(s):                       1 
  8. NUMA node(s):                    1 
  9. Vendor ID:                       GenuineIntel 
  10. Model name:                      Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz 
  11. L1d cache:                       192 KiB 
  12. L1i cache:                       192 KiB 
  13. L2 cache:                        1.5 MiB 
  14. L3 cache:                        12 MiB 

可以看到筆記本有一個Intel i7的處理器,6核12線程。經(jīng)查,CPU0和CPU6共用一個Core,CPU1和CPU7共用一個Core,以此類推。

以下的測試(Test 1-5)中,每個線程分別計算斐波那契數(shù)列第40億號元素的數(shù)值。

Test1:采用默認配置,開12線程進行測試。測試結果為總耗時45.003s。

  1. qhw@qhw-laptop:~/develop/smt_test$ time ./smt_test -f 4000000000 
  2. threads_num=12, fibonacci_max=4000000000, should_set_affinity=0, should_inline=1, alloc_granularity=32 
  3.   
  4. real0m45.003s 
  5. user7m12.953s 
  6. sys0m0.485s 

Test2:把smt關掉,同樣的測試方法(12線程)??偤臅r為25.733s。

  1. qhw@qhw-laptop:~/develop/smt_test$ cat turnoff_smt.sh 
  2. #!/bin/bash 
  3.  
  4. echo "turn off smt" 
  5. sudo sh -c 'echo off > /sys/devices/system/cpu/smt/control' 
  6. qhw@qhw-laptop:~/develop/smt_test$ ./turnoff_smt.sh 
  7. turn off smt 
  8. qhw@qhw-laptop:~/develop/smt_test$ time ./smt_test -f 4000000000 
  9. threads_num=12, fibonacci_max=4000000000, should_set_affinity=0, should_inline=1, alloc_granularity=32 
  10.   
  11. real0m25.733s 
  12. user2m23.525s 
  13. sys0m0.116s 

對,你沒看錯。同樣的workload,如果關掉smt,總耗時還變少了。Intel誠不欺我!

Test3:再次允許smt,但是將程序限制在三個物理Core上運行,則總耗時為34.896s。

  1. qhw@qhw-laptop:~/develop/smt_test$ ./turnon_smt.sh 
  2. turn on smt 
  3. qhw@qhw-laptop:~/develop/smt_test$ time taskset -c 0-2,6-8 ./smt_test -f 4000000000 
  4. threads_num=12, fibonacci_max=4000000000, should_set_affinity=0, should_inline=1, alloc_granularity=32 
  5.   
  6. real0m34.896s 
  7. user3m17.033s 
  8. sys0m0.028s 

Test3相比于Test1用了更少的Core,反而更快了。

為什么在Test2和3會出現(xiàn)這樣違反直覺的結果?

猜想:Cache一致性在作怪!

圖1

測試程序的main函數(shù)會分配一個含有T(T=nr_threads)個元素的`struct thread_info`類型的數(shù)組,并分別將每個元素作為參數(shù)傳遞給每個計算線程使用。`struct thread_info`定義如下:

  1. struct thread_info { 
  2. pthread_t thread_id; 
  3. int thread_num; 
  4. unsigned long res[2]; 
  5. }; 

結構體中的res數(shù)組用于計算斐波那契數(shù)列,因此會被工作線程頻繁地寫。

注意到,sizeof(struct thread_info)為32,而我的CPU的cacheline大小為64B!這意味著什么?

圖2

如圖所示,如果Thread 0在Core 0上運行,則它會頻繁寫tinfo[0],Thread 1在Core 1上運行,則它會頻繁寫tinfo[1]。

這意味著,當Thread 0寫tinfo[0]時,它其實是寫入了Core 0上L1 Cache的Cacheline。同樣的,當Thread 1寫tinfo[1]時,它其實是寫入了Core 1上L1 Cache的Cacheline。此時,由于Core 1上的Cacheline并非最新,因此CPU需要首先將Core 0中的Cacheline寫入多核共享的L3 Cache甚至是內(nèi)存中,然后再將其讀入Core 1的L1 Cache中,最后再將Thread 1的數(shù)據(jù)寫入。此時,由于Cache 0中的數(shù)據(jù)并非最新,Cacheline會被無效化。由此可見,如果程序一直這樣運行下去,這一組數(shù)據(jù)需要在Cache 0和1之間反復跳躍,占用較多時間。

這個猜想同樣可以解釋為什么使用較少的CPU可以加速程序運行。原因是當使用較少的CPU時,多線程不得不分時共用CPU,如果Thread 0和Thread 1分時共用了同一個CPU,則不需要頻繁將Cache無效化,程序運行時間也就縮短了。

驗證猜想:增加內(nèi)存分配粒度!

對程序進行修改后,可以使用`-g alloc_granularity`參數(shù)設定tinfo結構體的分配粒度。使用4KB為粒度進行分配,再次進行測試:

Test4:12線程,開啟SMT,分配粒度為4096??偤臅r為13.193s,性能相比于Test1的45.003s有了質(zhì)的提升!

  1. qhw@qhw-laptop:~/develop/smt_test$ time ./smt_test -f 4000000000 -g 4096 
  2. threads_num=12, fibonacci_max=4000000000, should_set_affinity=0, should_inline=1, alloc_granularity=4096 
  3.   
  4. real0m13.193s 
  5. user2m31.091s 
  6. sys0m0.217s 

Test5:在Test4的基礎上限制只能使用3個物理Core??偤臅r為24.841s,基本上是Test4的兩倍。這說明在這個測試下,多核性能還是線性可擴展的。

  1. qhw@qhw-laptop:~/develop/smt_test$ time taskset -c 0-2,6-8 ./smt_test -f 4000000000 -g 4096 
  2. threads_num=12, fibonacci_max=4000000000, should_set_affinity=0, should_inline=1, alloc_granularity=4096 
  3.   
  4. real0m24.841s 
  5. user2m26.253s 
  6. sys0m0.032s 

超線程SMT究竟可以快多少?

表格和結論:

 

測試名  硬件配置  運行時間(s)
Test6  “真”6核   38.562 
Test7 “假”6核  58.843
Test8 “真”3核   73.175 

測試使用的是6個工作線程。為了減少誤差,增加一點運行時間,每個線程計算斐波那契數(shù)列第200億項的值。

對比Test6和7,可以看到SMT的提升大概在52.6%左右。

測試記錄:

Test6:別名“真”6核,使用6個關閉了SMT的物理核進行計算??偤臅r為38.562s。

Test7:別名“假”6核,使用3個開啟了SMT的物理核進行計算??偤臅r為58.843s。

Test8:別名“真”3核,使用3個關閉了SMT的物理核進行計算。總耗時為1m13.175s。

  1. qhw@qhw-laptop:~/develop/smt_test$ cat test.sh 
  2. #!/bin/bash 
  3.  
  4. fibonacci=20000000000 
  5. sudo printf "" 
  6.   
  7. ./turnoff_smt.sh 
  8. time ./smt_test -f $fibonacci -g 4096 -t 6 
  9.   
  10. ./turnon_smt.sh 
  11. time taskset -c 0-2,6-8 ./smt_test -f $fibonacci -g 4096 -t 6 
  12.   
  13. ./turnoff_smt.sh 
  14. time taskset -c 0-2,6-8 ./smt_test -f $fibonacci -g 4096 -t 6 
  15.   
  16. ./turnon_smt.sh 
  17. qhw@qhw-laptop:~/develop/smt_test$ ./test.sh 
  18. turn off smt 
  19. threads_num=6, fibonacci_max=20000000000, should_set_affinity=0, should_inline=1, alloc_granularity=4096 
  20.   
  21. real0m38.562s 
  22. user3m50.786s 
  23. sys0m0.000s 
  24. turn on smt 
  25. threads_num=6, fibonacci_max=20000000000, should_set_affinity=0, should_inline=1, alloc_granularity=4096 
  26.   
  27. real0m58.843s 
  28. user5m53.018s 
  29. sys0m0.005s 
  30. turn off smt 
  31. threads_num=6, fibonacci_max=20000000000, should_set_affinity=0, should_inline=1, alloc_granularity=4096 
  32.   
  33. real1m13.175s 
  34. user3m39.486s 
  35. sys0m0.008s 
  36. turn on smt 

 

責任編輯:武曉燕 來源: Linux閱碼場
相關推薦

2021-10-18 11:55:10

SMTCPU線程

2021-12-28 07:20:44

斐波那契數(shù)算法數(shù)字

2012-02-22 10:14:44

Java

2021-10-31 21:01:00

數(shù)列TypeScriptJava

2021-05-16 18:02:52

系統(tǒng)編程JavaScript

2021-05-08 08:28:38

Java數(shù)據(jù)結構算法

2021-03-15 06:04:47

斐波那契數(shù)列背包問題算法

2020-05-11 14:18:14

JavaScript斐波那契數(shù)列遞歸

2022-11-14 08:12:34

2023-06-13 06:51:15

斐波那契數(shù)算法

2024-03-25 08:00:00

C++遞歸函數(shù)

2017-07-10 16:23:29

線程CPU單核

2021-03-17 08:37:23

算法性能分析遞歸算法遞歸樹

2022-03-28 15:15:15

神經(jīng)網(wǎng)絡編程開發(fā)

2013-04-10 10:58:19

LambdaC#

2020-04-20 11:09:18

Python開發(fā)語言

2009-04-27 12:26:45

AMD單核Nehalem

2017-03-06 14:45:27

超線程技術處理器技術服務器

2020-11-23 08:53:34

堆Heap

2022-06-27 19:19:26

算法題青蛙跳臺階
點贊
收藏

51CTO技術棧公眾號