【问题标题】:Discover number of CPU cores using threads使用线程发现 CPU 内核数
【发布时间】:2014-10-08 13:26:38
【问题描述】:

我有一个任务,我必须在 Linux 上用 C 语言编写一个程序(我使用 CentOS),它使用线程/进程来确定 CPU 的内核数量。 首先,我尝试以毫秒/微秒为单位打印当前时间,因为我知道可以运行 1 个线程/核心(或 2 个使用 HT)。但是以毫秒为单位,超过 10 个线程打印了相同的时间,以微秒为单位,没有一个线程是相同的。 其次,我尝试用时钟测量线程的执行时间,鉴于我有 4 个内核,4 个线程同时执行的时间应该几乎与执行 1 一样长。但是我的程序都不能让我更接近这个数字CPU 的。 你能帮我提些建议吗?

程序打印当前时间:

pthread_t th[N];     

void* afis ()
{
    //time_t now;
    //time(&now);
    //printf("%s", ctime(&now));
    struct timeval start, end;
    long mtime, seconds, useconds;    

    gettimeofday(&start, NULL);
    // usleep(2000);
    gettimeofday(&end, NULL);

    seconds  = end.tv_sec  - start.tv_sec;
    useconds = end.tv_usec - start.tv_usec;

    mtime = seconds + useconds;

    printf("Thread with TID:%d   Elapsed time: %ld microsecons\n",(unsigned int)pthread_self(), mtime);
}     

int main()
{
    int i;
    for (i=0;i<N;i++)
    {
        pthread_create(&th[i],NULL,afis,NULL);
    }
    for(i=0;i<N;i++)
    {
        pthread_join(th[i],NULL);
    }
    return 0;
}

程序测量处理时间:

pthread_t th[N];    

void* func(void* arg)
{
    int x;
    int k;
    int n=(int)arg;
    for(k=0;k<10000000;k+=n)
    {
        x=0;
    }
}


int main()
{
    int i,j;
    for (i=0;i<N;i++)
    {
        clock_t start, end, total;
        start=clock();
        for(j=0;j<i;j++)
        {
            printf("execution nr: %d\n",i);
            pthread_create(&th[j],NULL,func,(int*)i);
        }
        for(j=0;j<i;j++)
        {
            pthread_join(th[j],NULL);
        }
        end=clock();
        printf("start = %ld, end = %ld\n", start, end);
        total=((double)(end-start) )/ CLOCKS_PER_SEC;
        printf("total=%ld\n",total);
    }

    return 0;
}

【问题讨论】:

  • 我在答案中添加了一个想法。

标签: c multithreading cpu


【解决方案1】:

你应该做的是(在伪代码中):

get the actual time (start time)
start 40 threads
    each busy for one second;
wait for all of them to stop
get the actual time (stop time)

如果你分析一下这40个线程执行所用的时间,你就会知道核心的数量,或者至少你可以做一个假设:

if the time was around 40s: you have one core
else if the time was around 20s: you have two
and so on

您当然可以调整启动的线程数以及让它们休眠的时间,但我想如果您只休眠一毫秒,由于上下文切换和后台任务,您可能会得到不具有代表性的时间.


不要在线程中休眠,而是执行以下操作:

highlyCpuIntensiveTask()
{
    //calculate something that takes up the time x (best would be above 1 second)
}

你在不启动线程的情况下执行一次,会占用x 的时间。该时间将作为参考时间。

如果通过添加越来越多的pthreads (y),执行相同的功能,你所用的时间不会比x 多得多,那么你知道你很可能至少有@ 987654328@ 核心。在某些时候,使用z 线程,时间将在2x 左右,此时您将知道您拥有z-1 内核。

【讨论】:

  • 我怎样才能等待所有线程完成?如果我使用互斥锁,那么一次只有 1 个线程能够访问该函数,并且对于 4 个内核,应该可以有 4 个线程一次访问它
  • ??我预计花费的时间约为 1 秒,无论您启动多少线程,即使在单核系统上也是如此。
  • @MartinJames 你说得对,当然需要忙着等待。我的错。
  • “执行高度并行计算并测量其加速”的方法非常普遍,当然可以将这些周期用于具有良好并行性而不是忙于等待的一些有趣(甚至可能有用)的问题。
  • 感谢您的帮助。我解决了创建函数检查数字是否为 1 到 100k 的素数的问题(首先使用 1 个线程,然后使用 2,依此类推)。我在 linux 命令行中使用“time ./program”检查了执行时间。因此我可以确定我的 CPU 正在运行多少个内核。
【解决方案2】:
#include <unistd.h>

int number_of_cores = sysconf(_SC_NPROCESSORS_ONLN);

这不是可移植的,仅适用于 Linux afaik。

【讨论】:

  • 感谢您的帮助,但问题是我不允许以任何形式询问处理器,我需要使用线程/进程来确定它
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-09
  • 1970-01-01
  • 1970-01-01
  • 2019-02-15
  • 1970-01-01
  • 2020-04-23
相关资源
最近更新 更多