日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

linux的线程实验的实验结果,Linux线程qps测试

發布時間:2024/9/27 linux 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 linux的线程实验的实验结果,Linux线程qps测试 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本實驗源自該開源項目需求

https://github.com/yds086/HereticOS

實驗環境

OS ? ? : Centos 7.1

Kernel: 4.6.0

CPU ? :?Intel(R) Xeon(R) CPU E5-2620 v2 @ 2.10GHz (開啟超線程)

MEM : 48G DDR3

修改如下系統參數以創建盡量多的線程

/proc/sys/kernel/pid_max #操作系統線程數限制

/proc/sys/kernel/threads-max? #操作系統線程數

max_user_process(ulimit -u)#系統限制某用戶下最多可以運行多少進程或線程

ulimit -s 512 #修改線程棧大小

/proc/sys/vm/max_map_count #單進程mmap的限制會影響當個進程可創建的線程數

/proc/sys/kernel/threads-max 這個值需要注意下:

4.6.0的內核中,該值:

threads = div64_u64((u64) totalram_pages * (u64) PAGE_SIZE,

(u64) THREAD_SIZE * 8UL);

即48GB的內存,可以創建的threads-max為:

totalram_pages =?49432356KB/4KB =?12358089

threads =?12358089*4kB / (8kB * 8) =?772380

理論上可已得到應該是772380的線程數目,但不知為何,實際threads-max參數最多可以設置到772380/2 = 386190

偽代碼

//任務模式

long long g_SleepIoCount=0;

long long g_SleepIoLastCount=0;

void IOTask()

{

for(;;)

{

Sleep(100);// 100 ms 1000ms 10000ms

g_SleepIoCount++;

}

}

void TestIo()

{

//創建一組并發任務

CreatTask(IOTask,1000000);

//監測IO計數

for(;;)

{

Sleep(3000)//3s統計一次

printf("Sleep Iops %d",(g_SleepIoCount-g_SleepIoLastCount)/3);

}

}

測試代碼

#define _GNU_SOURCE

#include #include #include #include #include #include #include uint32_t g_sleep_ms = 0;

uint32_t g_threadcnt = 0;

uint32_t g_running_threadcnt = 0;

uint64_t g_SleepIoCount = 0;

int32_t g_main_bind = -1;

int32_t g_task_bind = -1;

#define USE_CORE_BIND 1

#define MSLEEP(x) usleep(1000 * (x))

#define ATOMIC_FETCH_AND_ADD(ptr,value) __sync_fetch_and_add((ptr), (value))

void *sleep_task(void* para)

{

if (g_task_bind >= 0)

{

cpu_set_t mask;

CPU_ZERO(&mask);

CPU_SET(g_task_bind, &mask);

if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0)

{

printf("Bind to Core Error !\n");

return NULL;

}

}

ATOMIC_FETCH_AND_ADD(&g_running_threadcnt, 1);

while(1)

{

MSLEEP(g_sleep_ms);

ATOMIC_FETCH_AND_ADD(&g_SleepIoCount, 1);

}

}

static inline pid_t gettid(void){

return syscall(SYS_gettid);

}

void execute_cmd(const char *cmd, char *result)

{

char buf_ps[1024];

char ps[1024]={0};

FILE *ptr;

strcpy(ps, cmd);

if((ptr=popen(ps, "r"))!=NULL)

{

while(fgets(buf_ps, 1024, ptr)!=NULL)

{

strcat(result, buf_ps);

if(strlen(result)>1024)

break;

}

pclose(ptr);

ptr = NULL;

}

else

{

printf("popen %s error\n", ps);

}

}

void print_process_info(void)

{

char cmd_string[128] = {0};

char cmd_result[128] = {0};

pid_t my_pid = gettid();

memset(cmd_string, 0, sizeof(cmd_string));

memset(cmd_result, 0, sizeof(cmd_result));

sprintf(cmd_string, "cat /proc/%u/status | grep VmRSS | cut -d : -f 2 | tr -cd \"[0-9]\"", (uint32_t)my_pid);

execute_cmd(cmd_string, cmd_result);

printf("Current Process Used %s physical memory !!!!\n", cmd_result);

memset(cmd_string, 0, sizeof(cmd_string));

memset(cmd_result, 0, sizeof(cmd_result));

sprintf(cmd_string, "cat /proc/%u/status | grep VmSize | cut -d : -f 2 | tr -cd \"[0-9]\"", (uint32_t)my_pid);

execute_cmd(cmd_string, cmd_result);

printf("Current Process Used %s virtual memory !!!!\n", cmd_result);

memset(cmd_string, 0, sizeof(cmd_string));

memset(cmd_result, 0, sizeof(cmd_result));

sprintf(cmd_string, "cat /proc/%u/status | grep Threads | cut -d : -f 2 | tr -cd \"[0-9]\"", (uint32_t)my_pid);

execute_cmd(cmd_string, cmd_result);

printf("Current Process Used %s threads !!!!\n", cmd_result);

sleep(3);

return ;

}

void main(int argc, void* argv[])

{

if (argc != 5)

{

printf("Usage:$s thread_cnt sleep_ms main_bind task_bind \n", argv[0]);

return;

}

g_threadcnt = atoi(argv[1]);

g_sleep_ms = atoi(argv[2]);

g_main_bind = atoi(argv[3]);

g_task_bind = atoi(argv[4]);

if (g_main_bind >= 0)

{

cpu_set_t mask;

CPU_ZERO(&mask);

CPU_SET(1, &mask);

if (pthread_setaffinity_np(pthread_self(), sizeof(mask), &mask) < 0)

{

printf("Main Bind to Core Error !\n");

return;

}

}

int ret = 0;

uint32_t i;

pthread_t thread;

for (i = 0; i < g_threadcnt; i++)

{

if (i % 5000 == 0)

{

printf("Already create %d threads ....\n", i);

}

ret = pthread_create(&thread, NULL, &sleep_task, NULL);

if (0 != ret)

{

printf("[ERROR]Create thread error, index:%d, ret:%d!!!\n", i, ret);

return;

}

}

//waiting for thread all running

while (g_running_threadcnt != g_threadcnt)

{

printf("Running:%d - Total:%d \n", g_running_threadcnt, g_threadcnt);

sleep(1);

}

printf("All the %d threads is running ....\n", g_running_threadcnt);

print_process_info();

//excute the test

uint64_t last_cnt = 0;

int test_cnt = 0;

for (; test_cnt < 50; test_cnt++)

{

sleep(3);

if (test_cnt != 0)

printf("Sleep Iops %d \n",(g_SleepIoCount-last_cnt)/3);

last_cnt = g_SleepIoCount; // maybe not accurate ...

}

print_process_info();

return;

}

Makefile

test:pthreadtest.c

gcc -g -O3 -o test ./pthreadtest.c -lpthread

clean:

rm -rf ./test

測試場景

單一核心上可以同時運行的最大線程數目

運行 ./test 325000 1000 1 2 , 即創建325000個線程,每個任務線程sleep 1s,同時主進程綁定在核心1上,任務線程均綁定在核心2上。

可以看出,主進程很快就創建完了325000個線程,但由于這些線程均綁定至核心2上,并且已經運行的線程只sleep 1s,導致需要運行的線程得不到時間片。

(用島主的話說:“那就是被io上限約束了吧, 再創建的都餓死,而不是都給點飯吃嗎”)

結論: 經過測試,本實驗環境下,在sleep 1s情況下,創建24w左右的線程可為極限。

單一進程進行核心綁定,得出單核的qps極限值

運行./test 26000 100 1 2

調整創建的線程數目,發現大于26000的線程后,創建線程將變的困難,和測試場景1屬于同樣的問題。

結論: 經過測試,本實驗環境下,在sleep 100ms情況下,單核qps極限值為25w左右,此時任務核心cpu跑滿100%

同樣的,時間擴大1倍至1s,線程數目擴大至250000,結果如下:(線性擴大至260000時,程序響應慢)

結論: 經過測試,本實驗環境下,在sleep 1000ms情況下,單核qps極限值為24w左右,此時任務核心cpu跑滿100%

我的環境下/proc/sys/kernel/threads-max最多30w左右(內存限制),導致無法測試10s的情況

同時運行多個進程,并進行核心綁定

同時執行./test 26000 100 1 2 和?./test 26000 100 3?4

測試結果:多核心的cpu,在此種測試結果下,qps基本成線性增加,(同時在物理核和超線程核心,會有一定影響)

將運行線程和sleep時間同時擴大10倍,即同時運行./test 240000 1000 1 2 和?./test 240000 1000 3?4: 測試結果如下

測試結果:多核心的cpu,在此種測試結果下,qps基本成線性增加,(同時在物理核和超線程核心,會有一定影響)

單一進程,不進行核心綁定

不進行核心綁定,由linux默認進行調度,理論上應該是25w * 12 的qps,在我的12核心cpu實驗環境下得到如下結果:

運行 ./test 190000 100 -1 -1

此時的cpu基本跑滿

如前述所說,和超線程也有一定的關系,所以并不一定是完全線性的。

測試結果:19w的線程,sleep 100ms,基本可以達到190w的qps,再進一步創建線程比較困難。

測試匯總

任務數

sleep?100ms

sleep?1000ms

26000

25w?qps

250000

24w?qps

180000

180w?qps

相關結論:

1)單個cpu核心的qps,可達25w qps;

2)多核心cpu,qps可擴展,基本符合線性,但超線程需關閉

總結

以上是生活随笔為你收集整理的linux的线程实验的实验结果,Linux线程qps测试的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。