多线程优化程序,我的程序
愚鬼 2007-01-14 01:18:01 程序在win2000下使用‘.net 2003’编译,测试运行正常,没有任何intel的工具可用,因为下载原因。
你们可以对源码重新编译运行。可能效果会更好。
优化主要是对循环进行的,首先是 updatepos中的循环改用进程支持,对于多核处理器,并行工作量要大一些,按页生成三个同类的进程,分别对页面进行操作,用开关量进行同步,在单处理器上优化效果不明显,因为还是顺序执行的原因。另外还有进程切换的开销。其次是对computpos进行的优化,也是按页面生成同类型的三个进程,计算pow点值,以每行的完成作为一个阶段,用开关量进行同步,使主进程与子进程并行运行。在单处理器上,反而更慢,因为进程切换开销和内存寻址开销的增加,在多核处理器上,应该更好一些。
因为没有能够下载到工具,因此没有使用优化工具,但是从程序算法原理上能够分析出,上述县城方案应该能够满足并行处理的要求,其他方面的小技巧本程序没有使用。
没有工具可以列出程序的运行数据。
/* compute the potential energy of a collection of */
/* particles interacting via pairwise potential */
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <windows.h>
#include <process.h> /* _beginthread, _endthread */
#include <time.h>
#define NPARTS 1000
#define NITER 201
#define DIMS 3
int rand( void );
int computePot(void);
void initPositions(void);
void updatePositions(void);
void updatePositions_New(void);
int computePot_New(void);
double r[DIMS][NPARTS];
double pot;
double distx, disty, distz, dist;
//
BOOL Update[DIMS];
BOOL Comput[DIMS];
double ComputResult[DIMS][NPARTS][NPARTS];
BOOL Result[DIMS][NPARTS];
BOOL ThreadQuit = FALSE;
DWORD WINAPI ThreadUpdatePos(void * Pointer);
DWORD WINAPI ThreadComputPos(void * Pointer);
int main() {
int i,jLine[DIMS];
;
clock_t start, stop;
initPositions();
//create threads
for(i=0;i<DIMS;i++){
Update[i]=FALSE;
Comput[i]=FALSE;;
jLine[i]=i;
CreateThread(NULL,0,ThreadUpdatePos,(void *)&jLine[i],0,NULL);
CreateThread(NULL,0,ThreadComputPos,(void *)&jLine[i],0,NULL);
}
updatePositions_New();
start=clock();
for( i=0; i<NITER; i++ ) {
pot = 0.0;
//computePot();
computePot_New();
if (i%10 == 0) printf("%5d: Potential: %10.3f\n", i, pot);
//updatePositions();
updatePositions_New();
}
stop=clock();
printf ("Seconds = %10.9f\n",(double)(stop-start)/ CLOCKS_PER_SEC);
ThreadQuit=TRUE;
getchar();
}
void initPositions() {
int i, j;
for( i=0; i<DIMS; i++ )
for( j=0; j<NPARTS; j++ )
r[i][j] = 0.5 + ( (double) rand() / (double) RAND_MAX );
}
void updatePositions(void) {
int i, j;
for( i=0; i<DIMS; i++ ){
for( j=0; j<NPARTS; j++ )
r[i][j] -= 0.5 + ( (double) rand() / (double) RAND_MAX );
}
}
void updatePositions_New(void){
int i;
for(i=0;i < DIMS;i++)
Update[i] = TRUE;
while((Update[0]==TRUE) || (Update[1]==TRUE) || (Update[2]==TRUE))
Sleep(0);
}
int computePot() {
int i, j;
for( i=0; i<NPARTS; i++ ) {
for( j=0; j<i-1; j++ ) {
distx = pow( (r[0][j] - r[0][i]), 2 );
disty = pow( (r[1][j] - r[1][i]), 2 );
distz = pow( (r[2][j] - r[2][i]), 2 );
dist = sqrt( distx + disty + distz );
pot += 1.0 / dist;
}
}
return 0;
}
int computePot_New(void)
{
int i,j;
for(i=0;i < DIMS;i++)
Comput[i] = TRUE;
//while((Comput[0]==TRUE) || (Comput[1]==TRUE) || (Comput[2]==TRUE))
// Sleep(0);
//
for(i=0;i<NPARTS;i++ ) {
while((Result[0][i]==FALSE) || (Result[1][i]==FALSE) || (Result[2][i] == FALSE))
Sleep(0);
//
Result[0][i]=FALSE;Result[1][i]=FALSE;Result[2][i]=FALSE;
for(j=0;j<i-1;j++){
dist = sqrt(ComputResult[0][i][j] + ComputResult[1][i][j] + ComputResult[2][i][j]);
pot += 1.0 / dist;
}
}
return 0;
}
DWORD WINAPI ThreadUpdatePos(void * Pointer)
{
int PosLine,iCount;
PosLine =*(int *)Pointer;
while(! ThreadQuit){
if (Update[PosLine] == TRUE){
for(iCount=0;iCount < NPARTS;iCount++){
r[PosLine][iCount] -= 0.5 + ( (double) rand() / (double) RAND_MAX );
}
Update[PosLine]=FALSE;
}else
Sleep(0);
}
return 0;
}
DWORD WINAPI ThreadComputPos(void * Pointer)
{
int PosLine,i,j;
PosLine =*(int *)Pointer;
while(! ThreadQuit){
if(Comput[PosLine] == TRUE){
for( i=0; i<NPARTS; i++ ) {
for( j=0; j<i-1; j++ ) {
//ComputResult[PosLine][i][j] = pow( (r[PosLine][j] - r[PosLine][i]), 2 );
ComputResult[PosLine][i][j] = (r[PosLine][j] - r[PosLine][i]) * (r[PosLine][j] - r[PosLine][i]);
}
Result[PosLine][i]=TRUE;
}
Comput[PosLine]=FALSE;
}else
Sleep(0);
}
return 0;
}