使用多线程时计算执行时间

标签 c multithreading winapi semaphore

多线程计算大量随机生成值的平均值是否更有效?

对于使用三个并行线程计算大量随机生成值的平均值的代码。我试着计算了两次执行时间。一次使用多线程,另一次只使用一个线程,但我不明白为什么多线程需要更长的执行时间。

#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <windows.h>
#include <time.h>

long int count=0,sum=0;
HANDLE ht1,ht2,ht3,Semaphore1,Semaphore2;

LARGE_INTEGER Start_time,End_time,Elapsed_time;
LARGE_INTEGER Frequency;


DWORD WINAPI Counter(LPVOID param)
{
long int i=0;

QueryPerformanceFrequency(&Frequency);
QueryPerformanceCounter(&Start_time);

    while (count<1000000)
    {
     WaitForSingleObject(Semaphore2,INFINITE);
     if(count<1000000)
     {
     count++;
     sum=sum+rand()%100;
     i++;
     }
    ReleaseSemaphore(Semaphore2,1,0);
    }
QueryPerformanceCounter(&End_time);
Elapsed_time.QuadPart = End_time.QuadPart - Start_time.QuadPart;
Elapsed_time.QuadPart =  (Elapsed_time.QuadPart * (1000))/ Frequency.QuadPart;

printf("Thread %d generated %d numbers\n",GetCurrentThreadId(),i);

ReleaseSemaphore(Semaphore1,1,0);
}


int main() {

    DWORD ThreadID1,ThreadID2,ThreadID3;
    char c;

    srand (time(NULL));

    ht1 = CreateThread(NULL,0,Counter,NULL,CREATE_SUSPENDED,&ThreadID1);
    ht2 = CreateThread(NULL,0,Counter,NULL,CREATE_SUSPENDED,&ThreadID2);
    ht3 = CreateThread(NULL,0,Counter,NULL,CREATE_SUSPENDED,&ThreadID3);

    Semaphore1=CreateSemaphore(NULL,0,1,NULL);
    Semaphore2=CreateSemaphore(NULL,1,1,NULL);

    printf("Thread 1 id is %d \n",ThreadID1);
    printf("Thread 2 id is %d \n",ThreadID2);
    printf("Thread 3 id is %d \n",ThreadID3);

    ResumeThread(ht1);
    ResumeThread(ht2);
    ResumeThread(ht3);

    WaitForSingleObject(Semaphore1,INFINITE);

    printf("Count reached %d \n",count);
    printf("Sum reached %d \n",sum);
    printf("Average is %f \n",(float)sum/(float)count);
    printf("Time in ms %d \n",Elapsed_time.QuadPart);

    while(c != 'e') {c = getche();}
    return 0;
}

我预计使用多线程的时间会少于使用一个线程的时间。 使用多线程输出是 2899 ms 仅使用一个线程输出为 947 毫秒

最佳答案

为了提高性能,多线程需要每个线程在共享临界区之外完成一些计算。在此代码中,所有计算都是由多个线程在单个共享临界区上竞争锁来完成的。实际上,该代码在逻辑上是单线程的,因为一次只能有一个线程持有临界区的锁。但是,添加更多线程会增加锁的争用和调度延迟,从而减慢单线程程序在没有锁定的情况下执行的计算速度。

要么找到一种在线程之间拆分任务的方法,以便它们在最后合并结果,要么使用一个线程。

关于使用多线程时计算执行时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55977551/

相关文章:

java 线程转储显示死锁症状

c - 自旋锁实现 (OSSpinLock)

c - 如何检索 native Windows 控件的正确大小?

c++ - 重定向子进程的输入和输出不起作用

c++ - 我是否必须分配SLIST_HEADER?

c - 调用 make 时找不到 MakeFile

c - 将 Haskell 中数组的指针传递给 C 函数

c - 带有参数 0 的 pthread_cleanup_pop?

c - 发生段错误是因为变量正在更改

java - 从可运行类更新 swing JEditorPane