【问题标题】:Single threading vs Multi threading in C by pthreadpthread在C中的单线程与多线程
【发布时间】:2018-08-24 11:09:59
【问题描述】:

我在这里尝试做的是通过做一个简单重复的操作来比较单线程和多线程的性能。所以我有两个线程将这个随机数 0xde 分配给这个数组,每个线程都占用数组的前半部分和后半部分,而单线程从索引 0 到末尾自行完成相同的工作。

我不明白的是,即使这些子线程只完成了单线程(即主线程)的一半工作,它们却要占用更多时间来完成任务!我不希望它花费一半的时间作为单线程,但我无法想象为什么它会比单线程花费更长的时间。

更令人惊讶的是,如果我将顺序切换为先执行单线程,那么我会得到我想要的结果。我真的可以在这方面使用一些帮助,因为这一切都在我脑海中一团糟。提前致谢!

ps。如果有帮助,我正在使用具有 4 个 ARM 处理器的 Raspberry Pi 3。 这是我得到的结果。 多线程1:46 毫秒
多线程2:50 毫秒
单线程:34 毫秒

#include <pthread.h>
#include <stdio.h>
#include <time.h>
#define SIZE 1000000

clock_t difference = 0;
clock_t difference1 = 0;
clock_t difference2 = 0;

void *substitute1(void *operand)
{
    int *arr = (int *)operand;
    int i=0;
    clock_t before1 = clock();

    for(i=0;i<(SIZE/2);i++)
    {
        arr[i] = 0x00de;
    }
    difference1 = clock() - before1;
    return NULL;
}


void *substitute2(void *operand)
{
    int *arr = (int *)operand;
    int i=0;
    clock_t before2 = clock();

    for(i=(SIZE/2);i<SIZE;i++)
    {
        arr[i] = 0x00de;
    }
    difference2 = clock() - before2;
    return NULL;
}

void single_thread(int *arr);

int main(void)
{
    int arr[SIZE];
    int test[SIZE];
    int msec1, msec2;


    // declare thread variables
    pthread_t thread1;
    pthread_t thread2;

    // create threads
    pthread_create(&thread1, NULL, substitute1, arr);
    pthread_create(&thread2, NULL, substitute2, arr);

    // wait untill the two threads do all their work
    while(arr[SIZE/2 - 1] != 0x00de) {/*printf("arr[%d] = %x\n", SIZE/2 - 1, arr[SIZE/2 -1]);*/};
    while(arr[SIZE-1] != 0x00de) {/*printf("arr[%d] = %x\n", SIZE-1, arr[SIZE-1]);*/};

    // and then join
    pthread_join(thread1, NULL);
    pthread_join(thread2, NULL);

    // convert clocks to milliseconds
    msec1 = difference1 * 1000 / CLOCKS_PER_SEC;
    msec2 = difference2 * 1000 / CLOCKS_PER_SEC;

    printf("Multithreading1 : %d ms\n", msec1);
    printf("Mulththreading2 : %d ms\n", msec2);

    // here's the single-threading
    single_thread(test);

    return 0;
}

void single_thread(int *arr) 
{
    int msec = 0, i = 0;

    // declare initial clock
    clock_t single_before = clock();

    for(i=0;i<SIZE;i++)
    {
        arr[i] = 0x00de;
    }

    difference = clock() - single_before;

    // convert clocks to milliseconds
    msec = difference * 1000 / CLOCKS_PER_SEC;
    printf("Singlethreading : %d ms\n", msec);

}

【问题讨论】:

  • '#define SIZE 1000000' 开始,添加另一个'0'。

标签: c multithreading performance pthreads


【解决方案1】:

嗨,多线程的性能可以通过大量数据来衡量。使用非常少量的数据,您无法衡量多线程应用程序的性能。原因:-

正如您所说,您的系统中有 4 个处理器,它们足以衡量您的情况下 2 个线程的性能。但是为什么它比单线程花费更多的时间。

  1. 要创建线程 O/S 需要为每个线程分配内存,这需要时间(即使它是微小的)。
  2. 创建多线程时,它需要上下文切换,这也需要时间。
  3. 需要释放分配给线程的内存,这也需要时间。

因此,当您尝试使用多线程进行小型操作时,它的性能将与单线程相同,甚至根本不适合。因此,在这种情况下,您的结果是前言。衡量多线程架构的性能,使用大量数据和复杂的操作,只有你才能看到差异。

现在只是为了理解,请参阅以下场景。只需考虑睡眠是函数完成其任务所需的总时间:-

只要像下面那样做,你就可以看到不同之处:-

void callme()
{
   printf("In callme()\n");
   sleep(2);
}

void main()
{
    //read the system time here
    callme();
    callme();
    callme();
    callme();
    callme();
    //read the system time here and check how much time it took in a single thread architecture 
    //it will take more than 10 sec
}

现在尝试使用多线程架构:-

void * callme(void *)
{
   printf("In callme()\n");
   sleep(2);
   return NULL; //better use pthread_exit(NULL);
}


void main()
{
    //read the system time here
    pthread_t thread1;
    pthread_t thread2;
    pthread_t thread3;
    pthread_t thread4;
    pthread_t thread5;


    pthread_create(&thread1, NULL, callme, NULL);
    pthread_create(&thread2, NULL, callme, NULL);
    pthread_create(&thread3, NULL, callme, NULL);
    pthread_create(&thread4, NULL, callme, NULL);
    pthread_create(&thread5, NULL, callme, NULL);

        pthread_join(thread1, NULL);
        pthread_join(thread2, NULL);
        pthread_join(thread3, NULL);
        pthread_join(thread4, NULL);
        pthread_join(thread5, NULL);   

      //read the system time here and check how much time it took in a single thread

    //it will take hardly 2.5 to 3 seconds benefit of 7 to 7.5 second than single thread
}

希望这能帮助你理解。

【讨论】:

  • 感谢您的评论。但是我只计算代码中的 for 循环的时间,所以我仍然无法解释为什么会发生这种情况。我可以考虑的唯一可能性是内存带宽,但话又说回来,当我将相同的任务分配给主线程和子线程时,执行时间会存在显着差异。这真的很难
  • 那是因为上下文切换。我已经提到过了。阅读有关多线程和上下文切换的信息,您将了解它。
【解决方案2】:

多线程程序的性能改进来自于在多个处理单元之间分配工作负载。因此,您的程序必须使用足够多的处理器来证明拆分工作负载是合理的。但是,您在这里所做的只是将数据写入内存,没有进行任何处理,因此您受到内存访问的限制,如here 所述。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-03-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-15
    • 1970-01-01
    • 2019-07-15
    相关资源
    最近更新 更多