gpt4 book ai didi

multithreading - 每个内核有多少个线程?

转载 作者:行者123 更新时间:2023-12-03 12:59:10 26 4
gpt4 key购买 nike

我正在计算机上运行一个具有 4核的多线程程序。我正在创建以SCHED_FIFO,SCHED_OTHER和SCHED_RR优先级运行的线程。可以同时运行的每种线程的最大数量是多少?

例如,
我很确定一次只能运行四个SCHED_FIFO线程(每个内核一个)
但我不确定其他两个。

按照要求编辑我的代码(虽然很长,但是大部分用于测试每个线程完成延迟任务的时间)

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>

void *ThreadRunner(void *vargp);
void DisplayThreadSchdStats(void);
void delayTask(void);

int threadNumber = 0;
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;

#define NUM_THREADS 9

//used to store the information of each thread
typedef struct{
pthread_t threadID;
int policy;
struct sched_param param;
long startTime;
long taskStartTime;
long endTime1;
long endTime2;
long endTime3;
long runTime;
char startDate[30];
char endDate[30];
}ThreadInfo;

ThreadInfo myThreadInfo[NUM_THREADS];



//main function
int main(void){

printf("running...\n");

int fifoPri = 60;
int rrPri = 30;

//create the 9 threads and assign their scheduling policies
for(int i=0; i<NUM_THREADS; i++){

if(i%3 == SCHED_OTHER){
myThreadInfo[i].policy = SCHED_OTHER;
myThreadInfo[i].param.sched_priority = 0;
}
else if (i%3 == SCHED_FIFO){
myThreadInfo[i].policy = SCHED_RR;
myThreadInfo[i].param.sched_priority = rrPri++;
}
else{
myThreadInfo[i].policy = SCHED_FIFO;
myThreadInfo[i].param.sched_priority = fifoPri++;
}
pthread_create( &myThreadInfo[i].threadID, NULL, ThreadRunner, &myThreadInfo[i]);
pthread_cond_wait(&cond, &mutex);
}

printf("\n\n");


//join each thread
for(int g = 0; g < NUM_THREADS; g++){
pthread_join(myThreadInfo[g].threadID, NULL);
}


//print out the stats for each thread
DisplayThreadSchdStats();


return 0;
}


//used to print out all of the threads, along with their stats
void DisplayThreadSchdStats(void){

int otherNum = 0;
long task1RR = 0;
long task2RR = 0;
long task3RR = 0;
long task1FIFO = 0;
long task2FIFO = 0;
long task3FIFO = 0;
long task1OTHER = 0;
long task2OTHER = 0;
long task3OTHER = 0;

for(int g = 0; g < threadNumber; g++){

printf("\nThread# [%d] id [0x%x] exiting...\n", g + 1, (int) myThreadInfo[g].threadID);
printf("DisplayThreadSchdStats:\n");
printf(" threadID = 0x%x \n", (int) myThreadInfo[g].threadID);

if(myThreadInfo[g].policy == 0){
printf(" policy = SHED_OTHER\n");
task1OTHER += (myThreadInfo[g].endTime1 - myThreadInfo[g].taskStartTime);
task2OTHER += (myThreadInfo[g].endTime2 - myThreadInfo[g].endTime1);
task3OTHER += (myThreadInfo[g].endTime3 - myThreadInfo[g].endTime2);
otherNum++;
}
if(myThreadInfo[g].policy == 1){
printf(" policy = SHED_FIFO\n");
task1FIFO += (myThreadInfo[g].endTime1 - myThreadInfo[g].taskStartTime);
task2FIFO += (myThreadInfo[g].endTime2 - myThreadInfo[g].endTime1);
task3FIFO += (myThreadInfo[g].endTime3 - myThreadInfo[g].endTime2);

}
if(myThreadInfo[g].policy == 2){
printf(" policy = SHED_RR\n");
task1RR+= (myThreadInfo[g].endTime1 - myThreadInfo[g].taskStartTime);
task2RR += (myThreadInfo[g].endTime2 - myThreadInfo[g].endTime1);
task3RR += (myThreadInfo[g].endTime3 - myThreadInfo[g].endTime2);

}



printf(" priority = %d \n", myThreadInfo[g].param.sched_priority);
printf(" startTime = %s\n", myThreadInfo[g].startDate);
printf(" endTime = %s\n", myThreadInfo[g].endDate);
printf(" Task start TimeStamp in micro seconds [%ld]\n", myThreadInfo[g].taskStartTime);
printf(" Task end TimeStamp in micro seconds [%ld] Delta [%lu]us\n", myThreadInfo[g].endTime1 , (myThreadInfo[g].endTime1 - myThreadInfo[g].taskStartTime));
printf(" Task end Timestamp in micro seconds [%ld] Delta [%lu]us\n", myThreadInfo[g].endTime2, (myThreadInfo[g].endTime2 - myThreadInfo[g].endTime1));
printf(" Task end Timestamp in micro seconds [%ld] Delta [%lu]us\n\n\n", myThreadInfo[g].endTime3, (myThreadInfo[g].endTime3 - myThreadInfo[g].endTime2));
printf("\n\n");


}

printf("Analysis: \n");
printf(" for SCHED_OTHER, task 1 took %lu, task2 took %lu, and task 3 took %lu. (average = %lu)\n", (task1OTHER/otherNum), (task2OTHER/otherNum), (task3OTHER/otherNum), (task1OTHER/otherNum + task2OTHER/otherNum + task3OTHER/otherNum)/3 );
printf(" for SCHED_RR, task 1 took %lu, task2 took %lu, and task 3 took %lu. (average = %lu)\n", (task1RR/otherNum), (task2RR/otherNum), (task3RR/otherNum), (task1RR/otherNum + task2RR/otherNum + task3RR/otherNum)/3 );
printf(" for SCHED_FIFO, task 1 took %lu, task2 took %lu, and task 3 took %lu. (average = %lu)\n", (task1FIFO/otherNum), (task2FIFO/otherNum), (task3FIFO/otherNum) , (task1FIFO/otherNum + task2FIFO/otherNum + task3FIFO/otherNum)/3);

}





//the function that runs the threads
void *ThreadRunner(void *vargp){


pthread_mutex_lock(&mutex);


char date[30];
struct tm *ts;
size_t last;
time_t timestamp = time(NULL);
ts = localtime(&timestamp);
last = strftime(date, 30, "%c", ts);
threadNumber++;
ThreadInfo* currentThread;
currentThread = (ThreadInfo*)vargp;


//set the start time
struct timeval tv;
gettimeofday(&tv, NULL);
long milltime0 = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000;
currentThread->startTime = milltime0;

//set the start date
strcpy(currentThread->startDate, date);

if(pthread_setschedparam(pthread_self(), currentThread->policy,(const struct sched_param *) &(currentThread->param))){
perror("pthread_setschedparam failed");
pthread_exit(NULL);
}

if(pthread_getschedparam(pthread_self(), &currentThread->policy,(struct sched_param *) &currentThread->param)){
perror("pthread_getschedparam failed");
pthread_exit(NULL);
}

gettimeofday(&tv, NULL);
long startTime = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000;
currentThread->taskStartTime = startTime;
//delay task #1
delayTask();

//set the end time of task 1
gettimeofday(&tv, NULL);
long milltime1 = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000;
currentThread->endTime1 = milltime1;


//delay task #2
delayTask();

//set the end time of task 2
gettimeofday(&tv, NULL);
long milltime2 = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000;
currentThread->endTime2 = milltime2;


//delay task #3
delayTask();

//set the end time of task 3
gettimeofday(&tv, NULL);
long milltime3 = (tv.tv_sec) * 1000 + (tv.tv_usec) / 1000;
currentThread->endTime3 = milltime3;


//set the end date
timestamp = time(NULL);
ts = localtime(&timestamp);
last = strftime(date, 30, "%c", ts);
strcpy(currentThread->endDate, date);


//set the total run time of the thread
long runTime = milltime3 - milltime0;
currentThread->runTime = runTime;

//unlock mutex
pthread_mutex_unlock(&mutex);
pthread_cond_signal(&cond);

pthread_exit(NULL);
}

//used to delay each thread
void delayTask(void){
for(int i = 0; i < 5000000; i++){
printf("%d", i % 2);
}

}

最佳答案

简而言之:不保证将并行运行多少个线程,但是所有线程将同时运行。

不管您在由通用操作系统控制的应用程序中启动了多少个线程,它们都将同时运行。也就是说,将为每个线程提供一些非零的运行时间,并且不能保证在OS定义的同步原语之外(等待互斥体,锁等)执行线程部分的特定执行顺序。线程数的唯一限制可以由OS的policies施加。

没有定义在任何给定的时间将选择多少个线程并行运行。该数量显然不能超过操作系统可见的逻辑处理器数量(请记住,操作系统本身可能在虚拟机中运行,并且存在诸如SMT之类的硬件技巧),并且您的线程将与同一系统中存在的其他线程竞争。操作系统确实提供了API,以查询哪些线程/进程当前处于运行状态,哪些线程/进程处于阻塞或就绪状态,但尚未计划,否则编写类似top的程序将成为问题。

显式为线程设置优先级可能会影响操作系统的选择,并增加并行执行线程的平均数量。请注意,如果不加思索地使用它,可能会有所帮助或受到伤害。但是,只要有其他进程,在多任务OS中它就永远不会严格等于四个。确保100%的时间将100%的CPU硬件专用于线程的唯一方法是在任何虚拟机管理程序之外的任何OS外部运行准系统应用程序(即使如此,也存在一些特殊之处,请参阅“英特尔系统管理模式”)。

在一个几乎闲置的通用操作系统中,如果您的线程是计算密集型的,我猜平均并行利用率为3.9-4.0。但丝毫没有动摇-所有赌注都没有了。

关于multithreading - 每个内核有多少个线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48723813/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com