多线程计算大量随机生成值的平均值是否更有效?
对于使用三个并行线程计算大量随机生成值的平均值的代码。我尝试两次计算执行时间。一次使用多线程,另一次仅使用一个线程,但是我不明白为什么多线程需要更长的执行时间。
#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毫秒 仅使用一个线程输出为947 ms
答案 0 :(得分:2)
为了提高性能,多线程处理需要每个线程在共享的关键部分之外进行一些计算。在此代码中,所有计算都是由多个线程竞争一个共享的关键部分上的锁来完成的。实际上,该代码在逻辑上是单线程的,因为一次最多只能有一个线程持有对该关键部分的锁定。但是,添加更多线程会增加争用并在锁定上安排等待时间,从而减慢单线程程序在不锁定的情况下执行的计算速度。
要么找到一种在线程之间分配任务的方法,以便它们在最后合并结果,要么使用一个线程。