15,466
社区成员
发帖
与我相关
我的任务
分享我运用C++语言,编写程序进行科学计算,用的是八核计算机,Windows系统
具体情况如下:有很多公用的常数,三个很大的数组Fi[750][750][2]和C[750][750][2]和Te[10000];具体的计算简单说就是:根据Fi[750][750][0]和C[750][750][0]和Te[i]先算出Fi[750][750][1],再算出C[750][750][1],然后再算出
Te[i+1](而算Te[i+1]时还要用到刚算出的Fi[750][750][1]和C[750][750][1]),一次循环结束。下一次循环,根据Fi[750][750][1]和C[750][750][1]和Te[i+1]先算出Fi[750][750][0],再算出C[750][750][0],然后再算出Te[i+2]](而算Te[i+2]时还要用到刚算出的Fi[750][750][0]和C[750][750][0]),总之就是[0]和[1]的数组来回颠倒着算,估计至少是10000步吧
我也看了一些多线程方面的书,编了如下的程序,可以说是模拟我说要进行的计算吧,可以运行,但仍有些担心和不满意,希望能给提些意见,毕竟我只是个外行
源代码如下:
#include <iostream>
#include <tchar.h>
#include <windows.h>
using namespace std;
//四个线程分别计算公用数组中的不同段
//每个线程进行相同的计算,但各自乘上一个不同的常数,以区别开
const int Te_Num=10;//t循环次数
//常数
const double con_Fi=20;
const double con_C=19;
const double con_Te=10;
int g_x=0;//全局变量
//公用数组
double Fi[20][2];
double C[20][2];
double Te[Te_Num+1];
CRITICAL_SECTION g_cx;
CRITICAL_SECTION g_cFi;
CRITICAL_SECTION g_cC;
CRITICAL_SECTION g_cTe;
int t=0;//时间变量,
DWORD WINAPI ThreadFun1(LPVOID lpParameter)//计算公用数组中的0~4段
{
//局部变量
double blockFi0;double blockC0;double blockTe0;
double blockFi1;double blockC1;
//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换互相计算以及C[][][0]和C[][][1]轮换互相计算
int tt=t%2;
int ttt=t%2;
for(int i=0;i <5;i++)
{
//当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运行性能
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把公用资源存放在局部变量blockFi0,blockC0,blockTe0中,以最大限度地减少关键代码段运行所花费的时间
blockFi0=Fi[i][tt];
blockC0=C[i][tt];
blockTe0=Te[t];
LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//模仿长时间计算,并把结果存放在临时变量blockFi1,blockC1,blockTe1中
Sleep(200);
blockFi1=1*(blockFi0+blockC0+blockTe0)/con_Fi;
blockC1=1*(blockFi0+blockC0+blockTe0)/con_C;
//
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把结果放回公用数组Fi[],C[],Te[]
Fi[i][ttt]=blockFi1;
C[i][ttt]=blockC1;
LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//改变全局变量g_x的值
EnterCriticalSection(&g_cx);
g_x++;
LeaveCriticalSection(&g_cx);
}
return 0;
}
DWORD WINAPI ThreadFun2(LPVOID lpParameter)//计算公用数组中的5~9段
{
double blockFi0;double blockC0;double blockTe0;
double blockFi1;double blockC1;
for(int i=5;i <10;i++)
{
//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换互相计算以及C[][][0]和C[][][1]轮换互相计算
int tt=t%2;
int ttt=t%2;
//当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运行性能
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把公用资源存放在局部变量blockFi0,blockC0,blockTe0中,以最大限度地减少关键代码段运行所花费的时间
blockFi0=Fi[i][tt];
blockC0=C[i][tt];
blockTe0=Te[t];
LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//模仿长时间计算,并把结果存放在临时变量blockFi1,blockC1,blockTe1中
Sleep(200);
blockFi1=2*(blockFi0+blockC0+blockTe0)/con_Fi;
blockC1=2*(blockFi0+blockC0+blockTe0)/con_C;
//
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把结果放回公用数组Fi[],C[],Te[]
Fi[i][ttt]=blockFi1;
C[i][ttt]=blockC1;
LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//改变全局变量g_x的值
EnterCriticalSection(&g_cx);
g_x++;
LeaveCriticalSection(&g_cx);
}
return 0;
}
DWORD WINAPI ThreadFun3(LPVOID lpParameter)//计算公用数组中的10~14段
{
double blockFi0;double blockC0;double blockTe0;
double blockFi1;double blockC1;
for(int i=10;i <15;i++)
{
//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换互相计算以及C[][][0]和C[][][1]轮换互相计算
int tt=t%2;
int ttt=t%2;
//当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运行性能
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把公用资源存放在局部变量blockFi0,blockC0,blockTe0中,以最大限度地减少关键代码段运行所花费的时间
blockFi0=Fi[i][tt];
blockC0=C[i][tt];
blockTe0=Te[t];
LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//模仿长时间计算,并把结果存放在临时变量blockFi1,blockC1,blockTe1中
Sleep(200);
blockFi1=3*(blockFi0+blockC0+blockTe0)/con_Fi;
blockC1=3*(blockFi0+blockC0+blockTe0)/con_C;
//
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把结果放回公用数组Fi[],C[],Te[]
Fi[i][ttt]=blockFi1;
C[i][ttt]=blockC1;
LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//改变全局变量g_x的值
EnterCriticalSection(&g_cx);
g_x++;
LeaveCriticalSection(&g_cx);
}
return 0;
}
DWORD WINAPI ThreadFun4(LPVOID lpParameter)//计算公用数组中的15~19段
{
double blockFi0;double blockC0;double blockTe0;
double blockFi1;double blockC1;
//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换互相计算以及C[][][0]和C[][][1]轮换互相计算
int tt=t%2;
int ttt=t%2;
for(int i=15;i <20;i++)
{
//当一个关键代码段长时间运行时,其他线程就会进入等待状态,这会降低应用程序的运行性能
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把公用资源存放在局部变量blockFi0,blockC0,blockTe0中,以最大限度地减少关键代码段运行所花费的时间
blockFi0=Fi[i][tt];
blockC0=C[i][tt];
blockTe0=Te[t];
LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//模仿长时间计算,并把结果存放在临时变量blockFi1,blockC1,blockTe1中
Sleep(200);
blockFi1=4*(blockFi0+blockC0+blockTe0)/con_Fi;
blockC1=4*(blockFi0+blockC0+blockTe0)/con_C;
//
EnterCriticalSection(&g_cFi);
EnterCriticalSection(&g_cC);
EnterCriticalSection(&g_cTe);
//把结果放回公用数组Fi[],C[],Te[]
Fi[i][ttt]=blockFi1;
C[i][ttt]=blockC1;
LeaveCriticalSection(&g_cFi);
LeaveCriticalSection(&g_cC);
LeaveCriticalSection(&g_cTe);
//改变全局变量g_x的值
EnterCriticalSection(&g_cx);
g_x++;
LeaveCriticalSection(&g_cx);
}
return 0;
}
void main()
{
//初始化Fi,C,Te数组
for(int i=0;i <20;i++)
{
Fi[i][0]=1;Fi[i][1]=1;C[i][0]=0.19;C[i][1]=0.19;
}
Te[0]=900;
HANDLE hThread1;
HANDLE hThread2;
HANDLE hThread3;
HANDLE hThread4;
for(t=0;t <Te_Num;t++)
{
//每次循环都把全局变量g_x置为零
g_x=0;
//初始化CriticalSection
InitializeCriticalSection(&g_cx);
InitializeCriticalSection(&g_cFi);
InitializeCriticalSection(&g_cC);
InitializeCriticalSection(&g_cTe);
//创建线程
hThread1=CreateThread(NULL,0,ThreadFun1,NULL,0,NULL);
hThread2=CreateThread(NULL,0,ThreadFun2,NULL,0,NULL);
hThread3=CreateThread(NULL,0,ThreadFun3,NULL,0,NULL);
hThread4=CreateThread(NULL,0,ThreadFun4,NULL,0,NULL);
CloseHandle(hThread1);
CloseHandle(hThread2);
CloseHandle(hThread3);
CloseHandle(hThread4);
while(g_x <20)//不断查询g_x,主线程等待所有辅助线程的计算完成//这麽处理是不是浪费CPU时间???
Sleep(10);
cout < <"Hello" < <endl;
DeleteCriticalSection(&g_cx);
DeleteCriticalSection(&g_cFi);
DeleteCriticalSection(&g_cC);
DeleteCriticalSection(&g_cTe);
//把时间t转换为0和1,以便实现对Fi[][][0]和Fi[][][1]轮换输出以及C[][][0]和C[][][1]轮换输出,以及Te[t+1]的计算
int ttt=(t+1)%2;
int tt=t%2;
//计算Te[t+1] 主线程会不会和副助主线程冲突 ???
for(int i=0;i <20;i++)
{
Te[t+1]=Te[t]+(Fi[i][tt]+C[i][tt])/con_Te;
}
cout < <g_x < <endl;
for(int i=0;i <20;i++)//主线程输出结果
{
cout < <Fi[i][tt] < <" " < <C[i][tt] < <" " < <Te[t] < <" " < <t < <endl;
}
}
}
CloseHandle(hThread1);
CloseHandle(hThread2);
CloseHandle(hThread3);
CloseHandle(hThread4);
while(g_x <20)//不断查询g_x,主线程等待所有辅助线程的计算完成//这麽处理是不是浪费CPU时间???
Sleep(10);