测试源码如下:
#define _GNU_SOURCE
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <pthread.h>
#include <stdint.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <fcntl.h>
typedef struct __test{
uint64_t a;
uint64_t b;
uint64_t c;
uint64_t d;
uint64_t e;
}test_t;
#define CPU_MAX 128
int cpuid[CPU_MAX];
test_t tdata[CPU_MAX];
int seq[CPU_MAX];
int thd_num = 1;
uint64_t prev[CPU_MAX];
uint64_t tmp[CPU_MAX];
int flag_stat = 0;
static void
init(void)
{
for(int i = 0; i < CPU_MAX; i++) {
cpuid[i] = -1;
seq[i] = i;
tdata[i].e = 100;
tdata[i].a = 0;
tdata[i].b = 0;
tdata[i].c = 0;
tdata[i].d = 0;
prev[i] = 0;
}
}
static int
parse_cpuid(const char *str)
{
char buf[256];
int flag_start = 0;
int thdnum = 0;
int len = strlen(str);
if(len > 255) {
memcpy(buf, str, 255);
buf[255] = 0;
}
else if(0 < len) {
strcpy(buf, str);
}
else return 0;
for(int i = 0; i < 256; i++) {
if(buf[i] == ' ' || buf[i] == '\t' || buf[i] == ',') buf[i] = 0;
}
for(int i = 0; i < 256; i++) {
if(flag_start && 0 == buf[i]) flag_start = 0;
if(0 == flag_start && 0 != buf[i]) {
flag_start = 1;
cpuid[thdnum] = atoi(buf+i);
if(0 > cpuid[thdnum] || CPU_MAX <= cpuid[thdnum]) return -1;
thdnum++;
}
}
return 0;
}
static int
parse_cmd(int argc, char **argv)
{
if(0 < argc) {
thd_num = atoi(argv[0]);
if(0 > thd_num) return -1;
argc--, argv++;
}
if(0 < argc) {
return parse_cpuid(argv[0]);
}
return 0;
}
static void*
task_root(void *arg)
{
register int seq = *(int*)arg;
int cid = cpuid[seq];
cpu_set_t cpumask;
pid_t pid = syscall(__NR_gettid);
if(0 <= cid && CPU_MAX > cid) {
//绑定 CPUID
CPU_ZERO(&cpumask);
CPU_SET(cid, &cpumask);
sched_setaffinity(pid, sizeof(cpumask), &cpumask);
usleep(1000);
printf("task[%d] run on cpuid=%d\n", seq, cid);
}
else {
printf("task[%d] run on cpuid=auto\n", seq);
}
while(1) {
tdata[seq].a += 1;
tdata[seq].b += tdata[seq].e*8;
tdata[seq].c += 1;
tdata[seq].d += tdata[seq].e*8;
}
return NULL;
}
static void*
stat_root(void *arg)
{
arg = arg;
uint64_t ttl;
uint64_t d10[CPU_MAX];
while(1) {
if(0 == flag_stat) {
usleep(1000);
}
else {
flag_stat = 0;
ttl = 0;
for(int i = 0; i < thd_num; i++) {
tmp[i] = tdata[i].a;
}
for(int i = 0; i < thd_num; i++) {
tmp[i] = tdata[i].a;
d10[i] = tmp[i] - prev[i];
ttl += d10[i];
}
printf("\nTotal do times: %lu(sec)\n", ttl/10);
for(int i = 0; i < thd_num; i++) {
if(-1 == cpuid[i]) {
printf("\ttask[%d] cpu=auto do times: %lu(/sec)\n", i, d10[i]/10);
}
else {
printf("\ttask[%d] cpu=%d do times: %lu(/sec)\n", i, cpuid[i], d10[i]/10);
}
prev[i] = tmp[i];
}
}
}
return NULL;
}
static void*
timer_root(void *arg)
{
arg = arg;
uint64_t ttl;
uint64_t d10[CPU_MAX];
while(1) {
sleep(10);
flag_stat = 1;
}
return NULL;
}
static int
task_set(void)
{
pthread_t thdid;
for(int i = 0; i < thd_num; i++) {
pthread_create(&thdid, NULL, task_root, &seq[i]);
}
pthread_create(&thdid, NULL, timer_root, NULL);
pthread_create(&thdid, NULL, stat_root, NULL);
return 0;
}
int main(int argc, char **argv)
{
//program thread-num thread-cpu-seq
init();
argc--, argv++;
if(-1 == parse_cmd(argc, argv)) {
printf("Input param error\n");
exit(-1);
}
task_set();
while(1) {
sleep(1000);
}
return 0;
}
双 CPU-4 核-超线程 Intel(R) Xeon(R) CPU E5620 @ 2.40GHz
逻辑 CPU 0 8 2 10 4 12 6 14 1 9 3 11 5 13 7 15
pysical id 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0
core id 0 0 1 1 9 9 10 10 0 0 1 1 9 9 10 10
系统:centos8
测试线程:
单线程绑定 0 逻辑 CPU 测试结果(执行累加次数) 108363138 (次 /秒)
双线程绑定 0,1 逻辑 CPU 测试结果(执行累加次数) 79961987 (次 /秒)
3 线程绑定 0,1,2 逻辑 CPU 测试结果(执行累加次数) 108639280 (次 /秒)
4 线程绑定 0,1,2,3 逻辑 CPU 测试结果(执行累加次数) 97511278 (次 /秒)
5 线程绑定 0,1,2,3,4 逻辑 CPU 测试结果(执行累加次数) 115751101 (次 /秒)
6 线程绑定 0,1,2,3,4,5 逻辑 CPU 测试结果(执行累加次数) 138198505 (次 /秒)
7 线程绑定 0,1,2,3,4,5,6 逻辑 CPU 测试结果(执行累加次数) 129034696 (次 /秒)
8 线程绑定 0,1,2,3,4,5,6,7 逻辑 CPU 测试结果(执行累加次数) 126871151 (次 /秒)
9 线程绑定 0,1,2,3,4,5,6,7,8 逻辑 CPU 测试结果(执行累加次数) 157512706 (次 /秒)
10 线程绑定 0,1,2,3,4,5,6,7,8,9 逻辑 CPU 测试结果(执行累加次数) 141989197 (次 /秒)
[结论]
增加线程数量并没有想象中的增加性能。
预期的目标应该是增加线程数(在同一个 CPU 中分配给不同的 CORE 的时候性能应该倍数增加,实际上没有),和预期的相差很大。
测试进程:
每个进程开始一个累加统计线程
测试结果
进程 1 绑定 CPU0 测试结果(执行累加次数) 102847956 (次 /秒)
进程 2 绑定 CPU2 测试结果(执行累加次数) 102903297 (次 /秒)
进程 3 绑定 CPU4 测试结果(执行累加次数) 102909125 (次 /秒)
进程 4 绑定 CPU6 测试结果(执行累加次数) 102934502 (次 /秒)
进程 5 绑定 CPU3 测试结果(执行累加次数) 107560180 (次 /秒)
假如开一个进程,绑定 CPU 和别的进程绑定的 CPU 在同一个 CPU 的同一个 CORE 下的话,性能会变成一半,两个进程加起来和单独只开一个进程的时候差不多,
[结论]
开进程处理数据没有相互影响,和预期的一样,增加进程性能倍数增加。
两个进程开在同一个 CPU 的同一个 CORE 中的时候性能减半,因为使用同一套 CORE 的计算单元,所以可以理解。
[疑问]
多线程的性能变化应该和多进程的一样预期,实际测试结果多线程的性能提升很少。(到底是什么因素导致的这个测试结果,没有思路,有知道的大佬能告诉一下吗???