多核并行编程实验报告

合集下载

多核多线程技术OpenMP_实验报告2

多核多线程技术OpenMP_实验报告2

实验二:OpenMP多线程编程模块一:基础练习3 编译执行,执行结果:简答与思考:1 写出关键的并行代码(1)四个线程各自执行6次迭代。

#include"stdafx.h"#include<omp.h>int _tmain(int argc, _TCHAR* argv[]){printf("Hello World \n");#pragma omp parallel{for(int i=0; i<6; i++){printf("Iter:%d Thread%d\n ",i,omp_get_thread_num());}}printf("GoodBye World\n");return 0;}(2)四个线程协同完成6次迭代。

#include"stdafx.h"#include<omp.h>int _tmain(int argc, _TCHAR* argv[]){printf("Hello World \n");#pragma omp parallel{#pragma omp forfor(int i=0; i<6; i++){printf("Iter:%d Thread%d\n ",i,omp_get_thread_num());}}printf("GoodBye World\n");return 0;}2 附加练习:(1)编译执行下面的代码,写出两种可能的执行结果。

int i=0,j = 0;#pragma omp parallel forfor ( i= 2; i < 7; i++ )for ( j= 3; j< 5; j++ )printf(“i = %d, j = %d\n”, i, j);可能的结果:1种2种i=2,j=3 i=2,j=3i=2,j=4 i=2,j=4i=3,j=3 i=3,j=3i=3,j=4 i=3,j=4i=6,j=3 i=5,j=3i=6,j=4 i=5,j=4i=4,j=3 i=5,j=3i=4,j=4 i=5,j=4i=5,j=3 i=6,j=3i=5,j=4 i=6,j=4(2)编译执行下面的代码,写出两种可能的执行结果。

多核编程与并行计算实验报告 (2)

多核编程与并行计算实验报告 (2)
if (ret_val != 0) {
printf("pthread_join error!\n");
exit(1);
} else {
printf("Thread %d return value is %0.15f\n", i,*retval_pi[i]);
}
}
printf("The value of Pi is %0.15f\n", pi);//输出pi的值
double d = 1.0/(N*THREAD_NUMBER);
double pi=0; //存储pi的值
sem_t sem; //信号量
void *thread(void *arg)
{
int *start = (int *)arg;
sem_wait(&sem); //若sem>0,sem--,线程往下执行;若sem<=0,线程将进入等待状态
return 0;
}
三、实验结果
四、程序改进
由于程序1用数组retval_pi[THREAD_NUMBER]分别存储每个线程的返回值,线程在运行时不相互影响,所以不必考虑互斥的问题。本程序只设置一个全局变量pi,每个线程都对pi进行计算。如果在某一时刻,几个线程同时对pi进行修改,就有可能出现数据不一致的情况,因此必须考虑线程互斥的问题。程序通过设置信号量的方法来实现线程互斥。建立一个初始值为1的信号量sem,当线程要修改pi的值时调用一次sem_wait(&sem)(若sem>0,则sem=sem--=0,线程可以执行;若sem=0,则已有线程在修改pi的值,线程陷入等待状态),修改完毕后再调用sem_post(&sem)(sem++),从而确保每次只能有一个线程修改pi的值。待线程全部执行完毕后,输出pi的值。

燕山大学多核程序设计实验报告

燕山大学多核程序设计实验报告

实验一Windows多线程编程一、实验目的与要求了解windows多线程编程机制掌握线程同步的方法二、实验环境和软件WindowsXPVC6.0三、实验内容创建线程:HANDLECreateThread(LPSECURITY_ATTRIBUTESlpThreadAttributes, SIZE_TdwStackSize,LPTHREAD_START_ROUTINElpStartAddress, LPVOIDlpParameter, DWORDdwCreationFlags, LPDWORDlpThreadId);四、实验程序#include"stdafx.h"#include<windows.h>#include<process.h>#include<iostream>#include<fstream>usingnamespacestd;voidThreadFrunc1(PVOIDparam){while(1){Sleep(1000);cout<<"ThisisThreadFrunc1"<<endl;}}voidThreadFrunc2(PVOIDparam){while(1){Sleep(1000);cout<<"ThisiskjjThreadFrunc2"<<endl; }}intmain(){inti=0;_beginthread(ThreadFrunc1,0,NULL);_beginthread(ThreadFrunc2,0,NULL);Sleep(3000);cout<<"end"<<endl;return0;}实验结果实验二蒙特卡罗法求PI一、实验目的和要求蒙特卡洛算法可理解为通过大量实验,模拟实际行为,来收集统计数据。

多核编程与并行计算实验报告 (1)

多核编程与并行计算实验报告 (1)

多核编程与并行计算实验报告姓名:日期:2014年 4月20日实验一// exa1.cpp : Defines the entry point for the console application.//#include"stdafx.h"#include<windows.h>#include<process.h>#include<iostream>#include<fstream>using namespace std;void ThreadFunc1(PVOID param){while(1){Sleep(1000);cout<<"This is ThreadFunc1"<<endl;}}void ThreadFunc2(PVOID param){while(1){Sleep(1000);cout<<"This is ThreadFunc2"<<endl;}}int main(){int i=0;_beginthread(ThreadFunc1,0,NULL);_beginthread(ThreadFunc2,0,NULL);Sleep(3000);cout<<"end"<<endl;return 0;}实验二// exa2.cpp : Defines the entry point for the console application. //#include"stdafx.h"#include<windows.h>#include<iostream>using namespace std;DWORD WINAPI FunOne(LPVOID param){while(true){Sleep(1000);cout<<"hello! ";}return 0;}DWORD WINAPI FunTwo(LPVOID param){while(true){Sleep(1000);cout<<"world! ";}return 0;}int main(int argc, char* argv[]){int input=0;HANDLE hand1=CreateThread (NULL, 0, FunOne, (void*)&input, CREATE_SUSPENDED, NULL); HANDLE hand2=CreateThread (NULL, 0, FunTwo, (void*)&input, CREATE_SUSPENDED, NULL);while(true){cin>>input;if(input==1){ResumeThread(hand1);ResumeThread(hand2);}else{SuspendThread(hand1);SuspendThread(hand2);}};TerminateThread(hand1,1);TerminateThread(hand2,1);return 0;}实验三// exa3.cpp : Defines the entry point for the console application.//#include"stdafx.h"#include<windows.h>#include<iostream>using namespace std;int globalvar = false;DWORD WINAPI ThreadFunc(LPVOID pParam){cout<<"ThreadFunc"<<endl;Sleep(200);globalvar = true;return 0;}int main(){HANDLE hthread = CreateThread(NULL, 0, ThreadFunc, NULL, 0, NULL);if (!hthread){cout<<"Thread Create Error ! "<<endl;CloseHandle(hthread);}while (!globalvar)cout<<"Thread while"<<endl;cout<<"Thread exit"<<endl;return 0;}实验四:// exa4.cpp : Defines the entry point for the console application. //#include"stdafx.h"#include<windows.h>#include<process.h>#include<iostream>#include<fstream>using namespace std;HANDLE evRead, evFinish;void ReadThread(LPVOID param){WaitForSingleObject (evRead ,INFINITE);cout<<"Reading"<<endl;SetEvent (evFinish);}void WriteThread(LPVOID param){cout<<"Writing"<<endl;SetEvent (evRead);}int main(int argc , char * argv[]){evRead = CreateEvent (NULL ,FALSE ,FALSE ,NULL) ;evFinish = CreateEvent (NULL ,FALSE ,FALSE ,NULL) ;_beginthread(ReadThread , 0 , NULL) ;_beginthread(WriteThread , 0 , NULL) ;WaitForSingleObject (evFinish,INFINITE) ;cout<<"The Program is End"<<endl;return 0 ;}实验五// exa5.cpp : Defines the entry point for the console application. //#include"stdafx.h"#include<windows.h>#include<process.h>#include<iostream>#include<fstream>using namespace std;int total = 100 ;HANDLE evFin[2] ;CRITICAL_SECTION cs ;void WithdrawThread1(LPVOID param){EnterCriticalSection(&cs) ;if ( total-90 >= 0){total -= 90 ;cout<<"You withdraw 90"<<endl;}elsecout<<"You do not have that much money"<<endl;LeaveCriticalSection(&cs) ;SetEvent (evFin[0]) ;}void WithdrawThread2(LPVOID param){EnterCriticalSection(&cs) ;if ( total-20 >= 0){total -= 20 ;cout<<"You withdraw 20"<<endl;}elsecout<<"You do not have that much money"<<endl;LeaveCriticalSection(&cs) ;LeaveCriticalSection(&cs) ;SetEvent (evFin[1]) ;}int main(int argc , char * argv[]){evFin[0] = CreateEvent (NULL,FALSE,FALSE,NULL) ;evFin[1] = CreateEvent (NULL,FALSE,FALSE,NULL) ;InitializeCriticalSection(&cs) ;_beginthread(WithdrawThread1 , 0 , NULL) ;_beginthread(WithdrawThread2 , 0 , NULL) ;WaitForMultipleObjects(2 ,evFin ,TRUE ,INFINITE) ;DeleteCriticalSection(&cs) ;cout<<total<<endl;return 0 ;}实验六:// exa6.cpp : Defines the entry point for the console application.//#include"stdafx.h"#include<windows.h>#include<iostream.h>#define THREAD_INSTANCE_NUMBER 3LONG g_fResourceInUse = FALSE;LONG g_lCounter = 0;DWORD ThreadProc(void * pData) {int ThreadNumberTemp = (*(int*) pData);HANDLE hMutex;cout << "ThreadProc: " << ThreadNumberTemp << " is running!" << endl;if ((hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "Mutex.Test")) == NULL) { cout << "Open Mutex error!" << endl;}cout << "ThreadProc " << ThreadNumberTemp << " gets the mutex"<< endl;ReleaseMutex(hMutex);CloseHandle(hMutex);return 0;}int main(int argc, char* argv[]){int i;DWORD ID[THREAD_INSTANCE_NUMBER];HANDLE h[THREAD_INSTANCE_NUMBER];HANDLE hMutex;if ( (hMutex = OpenMutex(MUTEX_ALL_ACCESS, FALSE, "Mutex.Test")) == NULL) { if ((hMutex = CreateMutex(NULL, FALSE, "Mutex.Test")) == NULL ) { cout << "Create Mutex error!" << endl;return 0;}}for (i=0;i<THREAD_INSTANCE_NUMBER;i++){h[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) ThreadProc,(void *)&ID[i],0,&(ID[i]));if (h[i] == NULL)cout << "CreateThread error" << ID[i] << endl;elsecout << "CreateThread: " << ID[i] << endl;}WaitForMultipleObjects(THREAD_INSTANCE_NUMBER,h,TRUE,INFINITE);cout << "Close the Mutex Handle! " << endl;CloseHandle(hMutex);return 0;}实验七// exa7.cpp : Defines the entry point for the console application.//#include"stdafx.h"#include<windows.h>#include<iostream.h>#define THREAD_INSTANCE_NUMBER 3DWORD foo(void * pData) {int ThreadNumberTemp = (*(int*) pData);HANDLE hSemaphore;cout << "foo: " << ThreadNumberTemp << " is running!" << endl;if ((hSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, "Semaphore.Test")) == NULL) {cout << "Open Semaphore error!" << endl;}cout << "foo " << ThreadNumberTemp << " gets the semaphore"<< endl;ReleaseSemaphore(hSemaphore, 1, NULL);CloseHandle(hSemaphore);return 0;}int main(int argc, char* argv[]){int i;DWORD ThreadID[THREAD_INSTANCE_NUMBER];HANDLE hThread[THREAD_INSTANCE_NUMBER];HANDLE hSemaphore;if ((hSemaphore = CreateSemaphore(NULL,0,1, "Semaphore.Test")) == NULL ) { cout << "Create Semaphore error!" << endl;return 0;}for (i=0;i<THREAD_INSTANCE_NUMBER;i++){hThread[i] = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) foo,(void *)&ThreadID[i],0,&(ThreadID[i]));if (hThread[i] == NULL)cout << "CreateThread error" << ThreadID[i] << endl;elsecout << "CreateThread: " << ThreadID[i] << endl;}WaitForMultipleObjects(THREAD_INSTANCE_NUMBER,hThread,TRUE,INFINITE);cout << "Close the Semaphore Handle! " << endl;CloseHandle(hSemaphore);return 0;}实验八:// exa8.cpp : Defines the class behaviors for the application.//#include"stdafx.h"#include"exa8.h"#include"MainFrm.h"#include"exa8Doc.h"#include"exa8View.h"#ifdef _DEBUG#define new DEBUG_NEW#undef THIS_FILEstatic char THIS_FILE[] = __FILE__;#endif///////////////////////////////////////////////////////////////////////////// // CExa8AppBEGIN_MESSAGE_MAP(CExa8App, CWinApp)//{{AFX_MSG_MAP(CExa8App)ON_COMMAND(ID_APP_ABOUT, OnAppAbout)// NOTE - the ClassWizard will add and remove mapping macros here.// DO NOT EDIT what you see in these blocks of generated code!//}}AFX_MSG_MAP// Standard file based document commandsON_COMMAND(ID_FILE_NEW, CWinApp::OnFileNew)ON_COMMAND(ID_FILE_OPEN, CWinApp::OnFileOpen)END_MESSAGE_MAP()/////////////////////////////////////////////////////////////////////////////// CExa8App constructionCExa8App::CExa8App(){// TODO: add construction code here,// Place all significant initialization in InitInstance}/////////////////////////////////////////////////////////////////////////////// The one and only CExa8App objectCExa8App theApp;/////////////////////////////////////////////////////////////////////////////// CExa8App initializationBOOL CExa8App::InitInstance(){AfxEnableControlContainer();// Standard initialization// If you are not using these features and wish to reduce the size// of your final executable, you should remove from the following// the specific initialization routines you do not need.#ifdef _AFXDLLEnable3dControls(); // Call this when using MFC in a shared DLL #elseEnable3dControlsStatic(); // Call this when linking to MFC statically#endif// Change the registry key under which our settings are stored.// TODO: You should modify this string to be something appropriate// such as the name of your company or organization.SetRegistryKey(_T("Local AppWizard-Generated Applications"));LoadStdProfileSettings(); // Load standard INI file options (including MRU) // Register the application's document templates. Document templates// serve as the connection between documents, frame windows and views.CSingleDocTemplate* pDocTemplate;pDocTemplate = new CSingleDocTemplate(IDR_MAINFRAME,RUNTIME_CLASS(CExa8Doc),RUNTIME_CLASS(CMainFrame), // main SDI frame windowRUNTIME_CLASS(CExa8View));AddDocTemplate(pDocTemplate);// Parse command line for standard shell commands, DDE, file openCCommandLineInfo cmdInfo;ParseCommandLine(cmdInfo);// Dispatch commands specified on the command lineif (!ProcessShellCommand(cmdInfo))return FALSE;// The one and only window has been initialized, so show and update it.m_pMainWnd->ShowWindow(SW_SHOW);m_pMainWnd->UpdateWindow();return TRUE;}///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App Aboutclass CAboutDlg : public CDialog{public:CAboutDlg();// Dialog Data//{{AFX_DATA(CAboutDlg)enum { IDD = IDD_ABOUTBOX };//}}AFX_DATA// ClassWizard generated virtual function overrides//{{AFX_VIRTUAL(CAboutDlg)protected:virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL// Implementationprotected://{{AFX_MSG(CAboutDlg)// No message handlers//}}AFX_MSGDECLARE_MESSAGE_MAP()};CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD){//{{AFX_DATA_INIT(CAboutDlg)//}}AFX_DATA_INIT}void CAboutDlg::DoDataExchange(CDataExchange* pDX){CDialog::DoDataExchange(pDX);//{{AFX_DATA_MAP(CAboutDlg)//}}AFX_DATA_MAP}BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)//{{AFX_MSG_MAP(CAboutDlg)// No message handlers//}}AFX_MSG_MAPEND_MESSAGE_MAP()// App command to run the dialogvoid CExa8App::OnAppAbout(){CAboutDlg aboutDlg;aboutDlg.DoModal();}///////////////////////////////////////////////////////////////////////////// // CExa8App message handlers、实验九:using System;using System.Threading;class Test{static void Main(){ThreadStart threadDelegate = new ThreadStart(Work.DoWork);Thread newThread = new Thread(threadDelegate);newThread.Start();Work w = new Work();w.Data = 42;threadDelegate = new ThreadStart(w.DoMoreWork);newThread = new Thread(threadDelegate);newThread.Start();}}class Work{public static void DoWork(){Console.WriteLine("Static thread procedure.");}public int Data;public void DoMoreWork(){Console.WriteLine("Instance thread procedure. Data={0}", Data);}实验十:using System;using System.Threading;class Test{static int total = 100;public static void WithDraw1(){int n=90;if (n <= total){total -= n;Console.WriteLine("You have withdrawn. n={0}", n);Console.WriteLine("total={0}", total);}else{Console.WriteLine("You do not enough money. n={0}", n);Console.WriteLine("total={0}", total);}}public static void WithDraw2()int n = 20;if (n <= total){total -= n;Console.WriteLine("You have withdrawn. n={0}", n);Console.WriteLine("total={0}", total);}else{Console.WriteLine("You do not enough money. n={0}", n);Console.WriteLine("total={0}", total);}}public static void Main(){ThreadStart thread1 = new ThreadStart(WithDraw1);Thread newThread1 = new Thread(thread1);ThreadStart thread2 = new ThreadStart(WithDraw2);Thread newThread2 = new Thread(thread2);newThread1.Start();newThread2.Start();}}实验十一:// exa11.cpp : Defines the entry point for the console application.//#include"stdafx.h"#include<windows.h>#include<conio.h>#include<stdio.h>#define THREAD_INSTANCE_NUMBER 3LONG g_fResourceInUse = FALSE;LONG g_lCounter = 0;CRITICAL_SECTION cs;DWORD ThreadProc1(void * pData) {int ThreadNumberTemp = (*(int*) pData);printf("ThreadProc1: %d is running!\n",ThreadNumberTemp );EnterCriticalSection(&cs);printf("ThreadProc1 %d enters into critical section\n",ThreadNumberTemp);Sleep(1000);LeaveCriticalSection(&cs);return 0;}DWORD ThreadProc2(void * pData) {int ThreadNumberTemp = (*(int*) pData);printf("ThreadProc2: %d is running!\n",ThreadNumberTemp );EnterCriticalSection(&cs);printf("ThreadProc2 %d enters into critical section\n",ThreadNumberTemp);Sleep(1000);LeaveCriticalSection(&cs);return 0;}int main(int argc, char* argv[]){int i;DWORD ID1,ID2;HANDLE h1,h2;InitializeCriticalSection(&cs);printf("Create the critical section \n");h1 = CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) ThreadProc1,(void *)&ID1,0,&(ID1));if (h1 == NULL)printf("CreateThread error %d \n",ID1);elseprintf("CreateThread %d \n",ID1);h2= CreateThread(NULL,0,(LPTHREAD_START_ROUTINE) ThreadProc2,(void *)&ID2,0,&(ID2));if (h2== NULL)printf("CreateThread error %d \n",ID2);elseprintf("CreateThread %d \n",ID2);WaitForSingleObject (h1,INFINITE);WaitForSingleObject (h2,INFINITE);printf("Delete the critical section \n");DeleteCriticalSection(&cs);getch();return 0;}。

并行程序实验报告

并行程序实验报告

并行程序设计实验报告姓名:学号:一、实验目的通过本次试验,了解使用OpenMP编程的基本方法和MPI的编程方法,通过实践实现的基本程序,掌握基本的线程及进程级并行应用开发技术,能够分析并行性能瓶颈及相应优化方法。

二、实验环境Linux操作系统,mpi库,多核处理器三、实验设计与实现(一)MPI并行程序设计用MPI编写一个greeting程序,编号为0的进程接受其它各进程的“问候”,并在计算机屏幕上显示问候情况。

用MPI编写一个多进程求积分的程序,并通过积分的方法求π的值,结果与π的25位精确值比较。

(二)多线程程序设计用Pthreads或OpenMP编写通过积分的方法求π的程序。

把该程序与相应的MPI程序比较。

用Pthreads或OpenMP编写编写矩阵相乘的程序,观察矩阵增大以及线程个数增减时的情形。

四、实验环境安装(一)MPI环境安装1.安装kylin操作系统的虚拟机(用VirtualBox)2.安装增强功能,使之与windows主机能够文件共享。

3.拷贝mpich-3.0.4.tar.gz到/root/myworkspace/目录下,并解压(tar xzf mpich-3.0.4.tar.gz)4.下面开始安装mkdir /root/myworkspace/mpi./configure --prefix=/root/myworkspace/mpi --disable-f77 --disable-fcmakemake install5.配置环境变量打开/root/.bashrc文件,在文件的末尾加上两行:PATH=$PATH:/root/myworkspace/mpi/binexport PATH保存退出,然后执行命令source /root/.bashrc(二)openMP实验环境安装Visual Studio中修改:项目->属性->c/c++->语言,将“OpenMP支持”改成“是”:五、实验结果及分析(一)MPI并行程序设计实验一:问候发送与接收非零号进程将问候的信息发送给0号进程,0号进程依次接收其它进程发送过来的消息并将其输出。

基于多核处理器的视频编解码并行算法研究的开题报告

基于多核处理器的视频编解码并行算法研究的开题报告

基于多核处理器的视频编解码并行算法研究的开题报告一、选题背景和意义随着多媒体技术的迅速发展,视频编解码技术得到广泛应用。

视频编解码是将视频信号中的冗余信息去除,压缩视频信号的数据量,从而达到节约存储空间和提高传输速度的目的。

随着高清视频、3D视频、VR/AR视频等技术的普及,对视频编解码的要求越来越高。

在视频编解码过程中,由于数据量大、复杂度高等原因,处理速度成为制约其应用的瓶颈。

而多核处理器的出现为视频编解码速度的提升提供了新的方法。

多核处理器可以同时执行多个线程,从而提高处理速度。

因此,研究基于多核处理器的视频编解码并行算法,对提高视频编解码的速度和效率具有重要意义。

二、研究内容和技术路线本课题拟研究基于多核处理器的视频编解码并行算法。

具体研究内容包括以下几个方面:1. 多核处理器的基本原理和编程模型:介绍多核处理器的基本原理,例如并发的数据流执行、共享存储器等,并介绍基于多核处理器的并行编程模型,例如OpenMP、CUDA等。

2. 视频编解码的基本原理和算法:介绍视频编解码的基本原理,例如码流分析、帧间帧内预测、离散余弦变换、量化、熵编码等,并介绍主流视频编解码算法,例如H.264、HEVC等。

3. 多核处理器并行优化算法:基于多核处理器的并行编程模型,针对视频编解码算法进行优化,例如帧间帧内预测并行、离散余弦变换并行、量化并行、熵编码并行等。

4. 系统实现和测试:在多核处理器平台上实现优化后的视频编解码算法,并对其进行测试和评估,包括压缩比、码率、图像质量等指标。

技术路线:(1)确定研究内容和目标。

(2)学习多核处理器的基本原理和编程模型,学习视频编解码的基本原理和算法。

(3)研究多核处理器并行优化算法,开发并行编程代码。

(4)在多核处理器平台上实现优化后的视频编解码算法,并对其进行测试和评估。

(5)撰写毕业论文及报告。

三、研究的创新点本文研究基于多核处理器的视频编解码并行算法,具有以下几个创新点:1. 结合多核处理器的并行计算能力,优化视频编解码算法的执行效率。

多核实验三

多核实验三

实验三OpenMP与Cilk编程实验报告一、实验目的●掌握OpenMP 3.0基本功能、构成语句、句法;●掌握OpenMP 3.0特点与创新之处;●掌握Cilk编程的基本方法;●掌握使用OpenMP进行多线程编程基本方法和调试;●掌握使用Intel Parallel Composer生成给予OpenMP优化可执行程序;二、实验条件硬件:1.Intel多核处理器2.大于1G内存3.大于20G硬盘软件:1.Intel Parallel Composer beta 1.0或更高版本2.熟练掌握C/C++语言3.掌握Microsoft Visual Studio 2005的开发环境使用;三、实验原理●OpenMP是由OpenMP Architecture Review Board牵头提出的,并已被广泛接受的,用于共享内存并行系统的多线程程序设计的一套指导性注释(Compiler Directive)。

OpenMP提供了对并行算法的高层的抽象描述,程序员通过在源代码中加入专用的pragma来指明自己的意图,由此编译器可以自动将程序进行并行优化,并在必要之处加入同步互斥以及通信。

英特尔® C++ 编译器的新功能Cilk 语言扩展技术为C/C++ 语言增加了细粒度任务支持,使其为新的和现有的软件增加并行性来充分发掘多处理器能力变得更加容易。

Cilk的设计特别适合但不限于“二分法”的算法。

它将问题分解成可以独立完成的子问题(任务),然后再将这些执行结果合并起来。

同时,Cilk的运行环境能有效率地将这些任务调度到空闲的处理器上运行。

一、实验步骤(一)H ello world 程序1、关闭病毒扫描和监控程序;2、采用VS2005 工具新建工程,并加入实验程序文件:helloworld.c;3、编译,运行程序并记录实验结果;4、在源程序代码中的找到主程序体:printf("Hello World\n");for(i=0;i<6;i++)printf("Iter:%d\n",i);;加上OpenMP 并行处理结构:#pragma omp parallel{}运行程序,记录并分析结果;(二)二积分方法求PI 值的并行处理化算法1、关闭病毒扫描和监控程序;2、采用VS2005工具打开实验程序文件:pi_serial.c;3、编译,运行程序并记录实验结果;4、在源程序代码中的找到主程序体中进行omp 方式优化#include "stdafx.h"#include "windows.h"#include <iostream>#include <time.h>using namespace std;const long num_steps = 1000000000;double step;int _tmain(int argc, _TCHAR* argv[]){int i;clock_t start, stop;double x, pi, sum = 0.0;step = 1.0/(double) num_steps;start = clock();#pragma omp parallel for private(x) reduction(+:sum)//for循环并行化for (i=0;i<= num_steps; i++){x = (i+0.5)*step;sum = sum + 4.0/(1.0+x*x);}#pragma omp critical//设置临界区pi = step * sum;stop = clock();printf("The value of PI is %15.12f\n",pi);printf("The time to calculate PI was %fseconds\n",((double)(stop - start)/1000.0));system("pause");return 0 ;}5、使用/Qopenmp 参数重新编译程序;6、设定Openmp 线程数:C:\>Set OMP_NUM_THREADS=4;7、重新运行程序,观测实验结果,并记录,分析采用OpenMP 前后程序性能差异;程序运行效率得到了极大地提高,运行时间由3秒多减少到1秒之内。

面向多核处理器的并行编程技术研究

面向多核处理器的并行编程技术研究

面向多核处理器的并行编程技术研究随着科技的发展和计算能力的提升,多核处理器已经成为了主流的处理器架构。

然而,要充分利用多核处理器的性能,需要掌握并行编程技术。

本文将对面向多核处理器的并行编程技术进行研究。

一、多核处理器简介先来了解一下多核处理器的概念。

多核处理器就是拥有多个处理器核心的处理器,可以同时处理多个任务。

与单核心处理器相比,多核处理器可以提高计算性能,减少任务执行时间。

多核处理器分为对称多处理(SMP)和非对称多处理(AMP)。

SMP是指拥有多个处理器,每个处理器都可以访问主内存,所有处理器的核心数和内存大小都相同。

AMP是指不同的处理器核心数量和内存大小不一样。

二、并行编程基础要掌握面向多核处理器的并行编程技术,需要先了解并行编程基础。

并行编程就是多个任务同时执行,紧密协作,以提高系统性能。

并行编程可以通过线程、进程、消息机制、消息队列等方式实现。

最常用的是线程和进程。

线程是指一个进程内的代码单元,拥有自己的栈空间,但是与其他线程共享进程的地址空间。

线程可用多种方式实现,例如pthread在Linux系统中。

线程可以达到真正的并行,用户自行管理线程的创建和销毁。

进程是指操作系统中运行的程序,并且分配了操作系统资源,例如内存空间、I/O操作、文件句柄等。

进程控制块(PCB)是用于存储有关进程信息的结构。

由于每个进程有自己的地址空间,因此进程之间的通信需要使用IPC(进程间通信)机制。

三、多线程实现并行编程多线程是实现面向多核处理器的并行编程技术的一种更加常用的方式。

多线程就是多个线程同时执行,在Linux系统中可以通过pthread库实现。

线程有独立的程序计数器,栈以及局部变量。

在进程内部,线程之间通过全局变量或者动态分配的内存等方式进行通信。

但是,线程通信的复杂度比单线程要高,因为需要保证线程之间的数据同步。

线程之间的通信主要有信号量、互斥量、条件变量、自旋锁等方式。

信号量被用于同步线程的进程,互斥量防止多个线程同时访问临界区,条件变量用于在线程间进行通信。

多核实验2-Intel Parallel Composer实验(Windows)

多核实验2-Intel Parallel Composer实验(Windows)

实验二Intel Parallel Composer实验(Windows)【实验目的】1.掌握Intel Parallel Composer的特点和基本使用方法;2.掌握在Windows下如何使用Intel Parallel Composer提高程序性能;【实验条件】硬件:1、Intel多核处理器2、大于1G内存3、大于20G硬盘软件:1、Intel Parallel Composer beta 1.0或更高版本2、熟练掌握C/C++语言3、掌握Microsoft Visual Studio 2005的开发环境使用;4、性能优化和给予多核编程的基本概念;【实验原理】1、Intel Parallel Composer主要功能与特点英特尔® Parallel Composer 是英特尔® Parallel Studio 的三大组件之一,Microsoft* Visual C++* 的开发人员能够使用它进行并行开发。

该产品将编译器、函数库和Microsoft Visual Studio* 调试器的扩展融为一体,更轻松、更快速地支持串行和多线程的并行。

Intel Parallel Composer有以下一些特点:●英特尔® C++ 完全兼容Microsoft Visual C++,支持最新的OpenMP* 技术,而且提供语言扩展来支持并帮助简化伪代码添加并行能力的工作。

●英特尔® Parallel Debugger Extension 可以简化并行调试并确保线程的准确性。

●英特尔® 线程构建模块和英特尔® 集成性能基元可提供已经线程化的通用和应用指定函数,从而支持开发人员迅速为应用程序添加并行能力。

Intel Parallel Composer包括以下的组件:●英特尔® C++ 编译器(Intel C++ Compiler)●英特尔® 线程构建模块(Intel Threading Building Blocks)●英特尔® 集成性能基元(Intel Integrated Performance Primitives)●英特尔® 并行调试器扩展Parallel Debugger ExtensionIntel c++编译器进行了更加底层的优化,可以充分的利用多核的资源,提高加速比。

多核实验报告

多核实验报告

实验报告课程名称:多核多线程技术院(系):信息与控制工程学院专业班级:计算机科学与技术姓名:学号:0906201指导教师:2012年11月21日实验一Windows API多线程编程本实验分为四个模块;分别为基础练习,临界区实验,事件实验,信号量实验。

通过本次实验逐步熟悉和掌握Win32 API多线程编程的语法结构、基本思路和方法。

理解API 之间的调用关系,参数的含义。

一、实验目的1、掌握MS V isual Studio 2010编写编译Win32 API多线程程序的方法;2、掌握Win 32 API编写多线程程序的语法;3、掌握Win 32 API编写多线程程序的思路;4、掌握Win 32多线程API的应用;5、能解决简单的数据竞争。

二、实验环境1、Windows XP系统2、Microsoft Visual Studio 2010三、相关知识1、内核对象的概念:由操作系统内核分配的,只能由内核访问的一个内存块,用来供系统和应用程序使用和管理各种系统资源。

2、Windows多线程API的基本管理线程的创建:HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes,DWORD dwStackSize,LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);线程的终止:VOID ExitThread(DWORD dwExitCode)BOOL CloseHandle (HANDLE hObject)线程的挂起与恢复:DWORD SuspendThread(HANDLE hThread)DWORD ResumeThread(HANDLE hThread)线程间的等待:DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);DWORD WaitForMultipleObjects (DWORD nCount,CONST HANDLE *lpHandles,BOOL fWaitAll,DWORD dwMilliseconds);3、线程间的同步与临界区相关的API:void WINAPI InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); void WINAPI EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection); void WINAPI DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection);与事件相关的API:HANDLE CreateEvent(LPSECURITY_ATTRIBUTES lpEventAttributes,BOOL bManualReset,BOOL bInitialState,LPCSTR lpName);DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);DWORD WaitForMultipleObjects (DWORD nCount,CONST HANDLE *lpHandles,BOOL fWaitAll,DWORD dwMilliseconds);BOOL SetEvent(HANDLE event );BOOL ResetEvent(HANDLE event );与信号量相关的API:HANDLE CreateSemaphore(LPSECURITY_ATTRIBUTES lpEventAttributes,LONG lSemInitial,LONG lSemMax,LPCSTR lpSemName);DWORD WaitForSingleObject(HANDLE hHandle,DWORD dwMilliseconds);DWORD BOOL ReleaseSemaphore(HANDLE hSemaphore,LONG cReleaseCount,LPLONG lpPreviousCount);四、实验原理线程是进程的一条执行路径,它包含独立的堆栈和CPU寄存器状态,每个线程共享所有的进程资源,包括打开的文件、信号标识及动态分配的内存等。

多核集群的MPI并行程序设计

多核集群的MPI并行程序设计

H a r b i n I n s t i t u t e o f T e c h n o l o g y并行处理与体系结构实验报告实验题目:多核集群的MPI并行程序设计院系:计算机科学与技术姓名:学号:实验日期: 2011-12-18哈尔滨工业大学实验三:多核集群的MPI并行程序设计一、实验目的1、理解并行计算的系统和模型,掌握并行计算的原理、方法、环境和工具。

理解并行编程的概念、环境和方法,理解消息传递编程模型。

2、掌握Linux下MPI并行集群环境的配置。

3、掌握MPI并行编程规范(1)掌握MPI的体系结构、特点(2)掌握MPI的基本语句、构成方式(3)能够分析和编写简单的MPI并行程序二、实验内容在Linux下建立并行集群环境,掌握如何在Linux下构建多核集群的并行计算环境。

在已经建立的Linux并行集群环境下编译运行C/C++语言MPI程序,并与串行程序进行比较,分析其性能变化。

三、实验原理并行计算的三种模式:1、共享内存:在这种模式下,所有的线程独立运作,但共享相同的内存资源。

例如,在一个多核心电脑上不同的线程共享内存里的矩阵、参数,等等。

这种模式在今天通常称为Symmetric Multiprocessor (SMP)。

这种模式下典型的并行计算程序可以使用OpenMP实现(一个API 的多平台共享存储并行编程)。

2、分布式内存:在这种模式下,进程(或处理器)都有自己的本地内存。

例如,内存可能会分布在整个网络,但是单个计算机上的每个线程只能用本地分配给它的内存。

甚至在同一台计算机上的不同进程都有独立的内存位置。

在这种模式下不同的进程通常需要与其他进程沟通以获取和发送数据。

在这种模式下典型的并行计算程序可以通过MPI(消息传递接口)实现。

3、混合分布式内存:在这种模式下,共享存储的单元通常是一个SMP节点。

在给定的SMP处理器上内存是通用共享的。

程序所需的总内存分布在多个SMP构成的网络上。

里仁多核程序设计实验报告

里仁多核程序设计实验报告
for (i = 0; i<short_len; i++)//-[]的前5000个数放入D[]
E[i] = B[i + 5000];//将B[]的后5000个数放入E[]
}
}
#pragma omp parallel default(none) shared(E,D,short_len) //private(i)------快速排序的并行region
#include "stdafx.h"
#include <omp.h>
#include <stdio.h>
#include <time.h>
#define NN 2000
int A[NN][NN], B[NN][NN];
long long C[NN][NN];
void solve(int n, int num_thread){
printf("\nTotal Time: %f ms.\n", dResult);
system("pause");
return 0;
}
五.结果分析
运行时间是串行的一半。明显降低了时间的消耗。
实验二
一.实验目的与要求
二.实验环境及软件
三.实验内容
以矩阵乘进行并行串行比较
四.实验代码和结果
实验代码:
// juzhencheng.cpp :定义控制台应用程序的入口点。
start_time=clock();
#pragma omp parallel sections reduction(+:sum) private(x,i)
{
#pragma omp section

多核求PI实验报告

多核求PI实验报告

Monte Carlo方法计算Pi一、实验要求以OpenMP实现Monte Carlo计算Pi的并行程序注意:制导循环编译共享变量的处理编译运行比较修改测试点数,提高计算精度。

利用OpenMP实现积分法,比较。

二、实验原理通过蒙特卡罗算法计算圆周率的主导思想是:统计学(概率)1.一个正方形有一个内切圆,向这个正方形内随机的画点,则点落在圆内的概论为P=圆面积/正方形面积。

2. 在一个平面直角坐标系下,在点(1,1)处画一个半径为R=1的圆,以这个圆画一个外接正方形,其边长为R=1(R=1时,圆面积即Pi)。

3. 随机取一点(X,Y)使得0<=X<=2R并且0<=Y<=2R,即随机点在正方形内。

4. 判断点是否在圆内,通过公式(X-R)(X-R)+(Y-R)(Y-R)<R*R计算。

5. 设所有点的个数为N,落在圆内的点的个数为M,则P=M/N=4*R*R/Pi*R*R=4/PiPi=4*N/M▪当实验次数越多(N越大),所计算出的Pi也越准确。

▪但计算机上的随机数毕竟是伪随机数,当取值超过一定值,也会出现不随机现象,因为伪随机数是周期函数。

如果想提高精度,最好能用真正的随机数生成器(需要更深的知识)。

三、实验步骤1.利用蒙特卡洛方法实现求PI值(利用OpenMP)思路:根据所给的串行程序,只需根据OpenMp的用法将其转换。

源码:#include"stdafx.h"#include<stdio.h>#include<time.h>#include<omp.h>#include<iostream>using namespace std;int _tmain(int argc, _TCHAR* argv[]){long max=1000000;long i,count=0;double x,y,bulk,starttime,endtime;time_t t;cout<<"请输入测试点的个数:"<<endl;cin>>max;starttime=clock();// 产生以当前时间开始的随机种子srand((unsigned) time(&t));#pragma omp parallel for num_threads(8) default(shared) private(x,y) reduction(+:count)for(i=0;i<max;i++){x=rand();x=x/32767;y=rand();y=y/32767;if((x*x+y*y)<=1)count++;}bulk=4*(double(count)/max);endtime= clock();printf("所得PI的值如下:%f \n", bulk);printf("计算PI的过程共用时间: %f 秒\n",(endtime-starttime)/ CLOCKS_PER_SEC);return 0;}2.利用积分法实现求PI(利用OpenMP)思路:与上同样道理。

多核编程实验报告1

多核编程实验报告1

实验一:Windows*Threads多线程编程模块一:基础练习1. 编译执行,输出结果:(1)简答与思考:修改后的HelloThreads的代码:1// HelloThreads.cpp : 定¡§义°?控?制?台¬¡§应®|用®?程¨¬序¨°的Ì?入¨?口¨²点Ì?。

¡ê23#include"stdafx.h"4#include<windows.h>5const int numThreads = 4;6DWORD WINAPI helloFunc(LPVOID pArg)7{8int j = *(int *)pArg;9printf("Hello Thread %d\n",j);10return 0;11}12int _tmain(int argc, _TCHAR* argv[])13{14 HANDLE hThread[numThreads];15int tNum[4];16for (int i = 0; i < numThreads; i++)17 { tNum[i]=i;18hThread[i] =19CreateThread(NULL, 0, helloFunc, &tNum[i], 0, NULL );20 }21 WaitForMultipleObjects(numThreads, hThread, TRUE, INFINITE);22return 0;23}运行结果图:(2)实验总结:模块二:临界区实验1.串行程序编译执行,Pi的值为:(截图)(3) 2.改为并行程序编译执行,Pi的值为:(截图)(4)简答与思考:3.如何进行并行化的?请写出并行化的思路与具体的代码。

多核研究性课题实验报告

多核研究性课题实验报告

辽宁师范大学计算机与信息技术学院综合性实验报告课程名称:多核并行程序设计实验题目:基于主成分分析的并行程序设计学生姓名:孙蕾专业:计算机科学与技术学号: 20101118050005实验日期: 2012年11月25日实验成绩:一、实验目的通过对主成分分析法进行研究,了解主成分分析在生产生活中的重要应用性。

在此基础上找到算法,给出计算对称矩阵特征值的串行算法,并在此基础上利用多核程序设计将其并行化,以优化运行速度。

通过本实验了解并行程序设计原理并达到基本能应用的水平。

二、实验内容1.对主成分分析法进行学习,明白其原理以及在现实生活中的应用方面和实际意义。

2.按照对主成分分析的理解找到计算特征值的算法并完成串行程序。

3.在串行程序的基础上应用多核程序设计的原理将程序并行化,分别对串行程序和并行程序计算运行时间,计算加速比,加深多核程序设计的理解。

4.总结研究中的问题以及克服方法,心得和体会。

三、实验过程(含结果抓图)1.串行程序代码及结果抓图#include<iostream.h>#include<stdlib.h>#include<math.h>#include<iomanip.h>//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //class Matrix定义矩阵类const int Max_xy=20; //矩阵的最大维数class Matrix{private:double data[Max_xy][Max_xy];unsigned x,y; //x,y;public:Matrix(); //默认构造函数Matrix(const Matrix & source); //拷贝构造函数void creat(); //输入矩阵void init();void transpose(); //矩阵转置void show(); //输入此矩阵double mode() const; //求一维矩阵的长度void check_shiduichen(); //检查是否为是对称矩阵void creat_unit(unsigned i); //生成i行单位矩阵void set_x(unsigned xx); //设置行数void set_y(unsigned yy); //设置列数unsigned get_x(); //得到行数unsigned get_y(); //得到列数void shucheng(double changshu); //数乘运算void setdata(unsigned i,unsigned j,double source); //定位输入数据double getdata(unsigned i,unsigned j); //定位得到数据void sturm(); //求特征值unsigned sturm_s(double m); //计算sturm系列的同好数Matrix operator = (const Matrix & right);friend Matrix & operator + (const Matrix & left,const Matrix & right); //重载+号friend Matrix & operator - (const Matrix & left,const Matrix & right); //重载-号friend Matrix & operator * (const Matrix & left,const Matrix & right); //重载乘号friend ostream& operator <<(ostream & os,const Matrix & source); //重载输出friend void Householder(Matrix & source); //用Householde矩阵将实对称矩阵化为三对角矩阵};Matrix temp_Matrix; //全局变量Matrix//===================================================================//--------------------默认构造函数Matrix::Matrix(){init();}//----------------------------拷贝构造函数Matrix::Matrix(const Matrix & source){init();x=source.x;y=source.y;for(unsigned i=0;i<x;i++)for(unsigned j=0;j<y;j++)data[i][j]=source.data[i][j];}//------------------------------------------初始化矩阵元素void Matrix::init(){x=y=0;for(unsigned i=0;i<Max_xy;i++)for(unsigned j=0;j<Max_xy;j++)data[i][j]=0;}//------------------------------矩阵转置void Matrix::transpose(){double temp;int t;for(unsigned i=0;i<Max_xy;i++)for(unsigned j=0;j<=i;j++){temp=data[i][j];data[i][j]=data[j][i];data[j][i]=temp;}t=x;x=y;y=t;}//--------------------------------------求一维矩阵的长度double Matrix::mode() const{double s=0;unsigned i,j;if(x==1)for(i=0,j=0;j<y;j++)s+=data[i][j]*data[i][j];else if(y==1)for(i=0,j=0;i<x;i++)s+=data[i][j]*data[i][j];else{cout<<"\n不是一维的!";exit(0);}s=sqrt(s);return (s);}//----------------------------------------重载=号Matrix Matrix::operator = (const Matrix & source){x=source.x;y=source.y;for(unsigned i=0;i<x;i++)for(unsigned j=0;j<y;j++)data[i][j]=source.data[i][j];return *this;}//-------------------------------------------重载+号Matrix & operator + (const Matrix & left,const Matrix & right){if(left.x!=right.x || left.y!=right.y){cout<<"\n维数不相等,不能相加!";exit(0);}for(unsigned i=0;i<left.x;i++)for(unsigned j=0;j<left.y;j++)temp_Matrix.data[i][j]=right.data[i][j] + left.data[i][j];temp_Matrix.x=right.x;temp_Matrix.y=right.y;return temp_Matrix;}//---------------------------------------------重载+号Matrix & operator - (const Matrix & left,const Matrix & right){if(left.x!=right.x || left.y!=right.y){cout<<"\n维数不相等,不能相减!";exit(0);}for(unsigned i=0;i<left.x;i++)for(unsigned j=0;j<left.y;j++)temp_Matrix.data[i][j]=left.data[i][j] - right.data[i][j];temp_Matrix.x=right.x;temp_Matrix.y=right.y;return temp_Matrix;}//----------------------------------------重载乘号Matrix & operator * (const Matrix & left,const Matrix & right){if(left.y!=right.x){cout<<"\n两个矩阵相乘错误.";exit(0);}temp_Matrix.init();unsigned i,j,k;for(i=0;i<left.x;i++)for(j=0;j<right.y;j++)for(k=0;k<left.y;k++)temp_Matrix.data[i][j]+=left.data[i][k] * right.data[k][j];temp_Matrix.x=left.x;temp_Matrix.y=right.y;return temp_Matrix;}//-------------------------------------------输入矩阵void Matrix::creat(){cout<<"输如行列式:";cout<<"\n行数:";cin>>x;cout<<"列数:";cin>>y;for(unsigned i=0;i<x;i++){cout<<"输入第"<<i+1<<"行:";for(unsigned j=0;j<y;j++)cin>>data[i][j];}}//----------------------------------------------输出矩阵void Matrix::show(){unsigned i,j;cout<<"\n\n矩阵表示如下:";for(i=0;i<x;i++){cout<<endl;for(j=0;j<y;j++)cout<<setw(7)<<setiosflags(ios::left)<<data[i][j];}}//----------------------------------用Householder矩阵化为实对称矩阵void Householder(Matrix & source){unsigned i,lenth,k,m,n,flag;double temp_lie_x[Max_xy],temp_lie_y[Max_xy],temp[Max_xy];double s;for(i=0;i<source.x-2;i++){for(k=0;k<Max_xy;k++){ //初始化为0temp_lie_x[k]=0;temp_lie_y[k]=0;temp[k]=0;}for(lenth=0;lenth+i+1<source.x;lenth++) //提取第data[i+1][i]到data[x-1][i]的数据存到temp_lie[Max_xy];temp_lie_x[lenth]=source.data[lenth+i+1][i];for(k=0,s=0;k<lenth;k++) //j为临时变量的个数.s+=temp_lie_x[k]*temp_lie_x[k];s=sqrt(s);temp_lie_y[0]=-s;for(k=1;k<lenth;k++)temp_lie_y[k]=0;for(k=0;k<lenth;k++)temp[k]=temp_lie_x[k]-temp_lie_y[k];for(k=0,flag=0;k<lenth;k++) //假如以上两个向量相等则退出,则跳出以进行下一次变换if(temp[k]!=0){flag=1;break;}if(flag==0)continue;Matrix part_h,I,x_y; //定义Matrix变量I.creat_unit(lenth);x_y.x=lenth,x_y.y=1;//对x_y赋值for(k=0;k<lenth;k++)x_y.data[k][0]=temp[k];//求x_y的转置Matrix zhuanzhi_x_y( x_y ); //拷贝构造函数zhuanzhi_x_y.transpose();s=2.0 / ( x_y.mode() * x_y.mode() );x_y.shucheng(s);temp_Matrix=x_y * zhuanzhi_x_y;part_h=I- x_y*zhuanzhi_x_y;Matrix H;H.creat_unit(source.x);for(m=i+1;m<source.x;m++)for(n=i+1;n<source.y;n++)H.data[m][n]=part_h.data[m-i-1][n-i-1]; //得到最后的Householder 矩阵source=source * H;source=H * source;}for(i=0;i<source.x;i++)for(k=0;k<source.y;k++)if(fabs(source.data[i][k]) < 1e-13)source.data[i][k]=0;//------------------------------------检查是否为实对称矩阵void Matrix::check_shiduichen(){if(x!=y){cout<<"\n\n不是是对称矩阵(行列不相等)\n\n";exit(0);}for(unsigned i=0;i<x;i++)for(unsigned j=0;j<y;j++){if(data[i][j]!=data[j][i]){cout<<"\n\n不是实对称矩阵!(不对称!)\n\n";exit(0);}}}ostream & operator <<(ostream & os,const Matrix & source){unsigned i,j;for(i=0;i<source.x;i++){os<<"\n";for(j=0;j<source.y;j++)os<<setw(10)<<setiosflags(ios::left)<<source.data[i][j]<<"\t";}os<<endl;return os;}void Matrix::set_x(unsigned xx) //设置行数{x=xx;}void Matrix::set_y(unsigned yy) //设置列数{y=yy;}unsigned Matrix::get_x() //得到行数{return x;}unsigned Matrix::get_y() //得到列数{return y;}double Matrix::getdata(unsigned i,unsigned j) //定位得到数据{return data[i][j];}void Matrix::setdata(unsigned i,unsigned j,double source){data[i][j]=source;if(x<i) x=i;if(y<j) y=j;}void Matrix::creat_unit(unsigned lenth) //生成i行单位矩阵{init();x=y=lenth;for(unsigned i=0;i<lenth;i++)data[i][i]=1;}void Matrix::shucheng(double changshu) //数乘运算{unsigned i,j;for(i=0;i<x;i++)for(j=0;j<y;j++)data[i][j]*=changshu;}void Matrix::sturm(){double s,r,maxhang,a,b;unsigned i,j,m;for(i=0,maxhang=0;i<x;i++){ for( s=0,j=0;j<y;j++)s+=fabs(data[i][j]);if(s>maxhang)maxhang=s;}a=-maxhang;b=maxhang;m=sturm_s(a)-sturm_s(b);for(i=1;i<=m;i++){a=-maxhang;b=maxhang;do{r=0.5*(a+b);if(sturm_s(r)>=i)a=r;elseb=r;}while(fabs(a-b)>1e-11);cout<<"\n特征值"<<i<<": "<<setiosflags(ios::left)<<setw(10)<<setprecision(10) <<setiosflags(ios::fixed)<<0.5*(a+b);}}unsigned Matrix::sturm_s(double r){double p[Max_xy+1];int temp[Max_xy+1];unsigned m,i;p[0]=1;p[1]=data[0][0]-r;for(i=2;i<=x;i++)p[i]=(data[i-1][i-1]-r)*p[i-1]-data[i-2][i-1]*data[i-2][i-1]*p[i-2];temp[0]=1;for(i=1;i<=x;i++)if(p[i]>1e-14)temp[i]=1;else if(p[i]<-1e-14)temp[i]=-1;elsetemp[i]=temp[i-1];for(i=1,m=0;i<=x;i++)if(temp[i]+temp[i-1]!=0)m++;return m;}int _tmain(int argc, _TCHAR* argv[]){double begin,end,time;begin=(double)clock()/(double)CLK_TCK;Matrix a;a.creat();cout<<"输º?入¨?的Ì?矩?阵¨®为a:";cout<<a;a.check_shiduichen();Householder(a);cout<<"用Householder化¡为实对称矩阵为a:";cout<<a;a.sturm();cout<<endl;end=(double)clock()/(double)CLK_TCK;time=end-begin;cout<<"时间是:";cout<<time;return 0;}串行运行结果:2.并行程序代码及结果抓图// bingxing.cpp : 定义控制台应用程序的入口点//// c.cpp : 定义控制台应用程序的入口点//#include "stdafx.h"#include <iostream>#include <stdlib.h>#include <math.h>#include <iomanip>#include <omp.h>using namespace s td;//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //class Matrix定¡§义°?矩?阵¨®类¤¨¤const int Max_xy=20;//矩?阵¨®的Ì?最Á?大䨮维?数ºyclass Matrix{private:double data[Max_xy][Max_xy];unsigned x,y; //x,y;public:Matrix(); //默?认¨?构1造¨¬函¡¥数ºyMatrix(const Matrix & source); //拷?贝À¡ä构1造¨¬函¡¥数ºyvoid creat(); //输º?入¨?矩?阵¨®void init();void transpose(); //矩?阵¨®转Áa置?void show(); //输º?入¨?此ä?矩?阵¨®double mode() const; //求¨®一°?维?矩?阵¨®的Ì?长¡è度¨¨void check_shiduichen(); //检¨¬查¨¦是º?否¤?为a是º?对?称?矩?阵¨®void creat_unit(unsigned i); //生¦¨²成¨¦i行D单Ì£¤位?矩?阵¨®void set_x(unsigned xx); //设¦¨¨置?行D数ºyvoid set_y(unsigned yy); //设¦¨¨置?列¢D数ºyunsigned get_x(); //得Ì?到Ì?行D数ºyunsigned get_y(); //得Ì?到Ì?列¢D数ºyvoid shucheng(double changshu); //数ºy乘?运?算?void setdata(unsigned i,unsigned j,double source); //定¡§位?输º?入¨?数ºy据Ydouble getdata(unsigned i,unsigned j); //定¡§位?得Ì?到Ì?数ºy据Yvoid sturm(); //求¨®特¬?征¡Â值¦Ìunsigned sturm_s(double m); //计?算?sturm系¦Ì列¢D的Ì?同ª?好?数ºy Matrix operator = (const Matrix & right);friend Matrix & operator + (const Matrix & left,const Matrix & right); //重?载?+号?friend Matrix & operator - (const Matrix & left,const Matrix & right); //重?载?-号?friend Matrix & operator * (const Matrix & left,const Matrix & right); //重?载?乘?号?friend ostream& operator <<(ostream & os,const Matrix & source); //重?载?输º?出?friend void Householder(Matrix & source); //用®?Householde矩?阵¨®将?实º¦Ì对?称?矩?阵¨®化¡¥为a三¨y对?角?矩?阵¨®};Matrix temp_Matrix; //全¨?局?变À?量¢?Matrix//===================================================================//--------------------默?认¨?构1造¨¬函¡¥数ºyMatrix::Matrix(){init();}//----------------------------拷?贝À¡ä构1造¨¬函¡¥数ºyMatrix::Matrix(const Matrix & source){init();x=source.x;y=source.y;for(unsigned i=0;i<x;i++)for(unsigned j=0;j<y;j++)data[i][j]=source.data[i][j];}//------------------------------------------初?始º?化¡¥矩?阵¨®元a素? void Matrix::init(){x=y=0;for(unsigned i=0;i<Max_xy;i++)for(unsigned j=0;j<Max_xy;j++)data[i][j]=0;}//------------------------------矩?阵¨®转Áa置?void Matrix::transpose(){double temp;int t;for(unsigned i=0;i<Max_xy;i++)for(unsigned j=0;j<=i;j++){temp=data[i][j];data[i][j]=data[j][i];data[j][i]=temp;}t=x;x=y;y=t;}//--------------------------------------求¨®一°?维?矩?阵¨®的Ì?长¡è度¨¨double Matrix::mode() const{double s=0;unsigned i,j;if(x==1)for(i=0,j=0;j<y;j++)s+=data[i][j]*data[i][j];else if(y==1)for(i=0,j=0;i<x;i++)s+=data[i][j]*data[i][j];else{cout<<"\n不?是º?一°?维?的Ì?!";exit(0);}s=sqrt(s);return (s);}//----------------------------------------重?载?=号?Matrix Matrix::operator = (const Matrix & source){x=source.x;y=source.y;for(unsigned i=0;i<x;i++)for(unsigned j=0;j<y;j++)data[i][j]=source.data[i][j];return *this;}//-------------------------------------------重?载?+号?Matrix & operator + (const Matrix & left,const Matrix & right){ int j;if(left.x!=right.x || left.y!=right.y){cout<<"\n维?数ºy不?相¨¤等̨¨,不?能¨¹相¨¤加¨®!";exit(0);}for(unsigned i=0;i<left.x;i++)#pragma omp parallel for private(j)for( j=0;j<left.y;j++)temp_Matrix.data[i][j]=right.data[i][j] + left.data[i][j];temp_Matrix.x=right.x;temp_Matrix.y=right.y;return temp_Matrix;}//---------------------------------------------重?载?-号?Matrix & operator - (const Matrix & left,const Matrix & right){if(left.x!=right.x || left.y!=right.y){cout<<"\n维?数ºy不?相¨¤等̨¨,不?能¨¹相¨¤减?!";exit(0);}for(unsigned i=0;i<left.x;i++)for(unsigned j=0;j<left.y;j++)temp_Matrix.data[i][j]=left.data[i][j] - right.data[i][j];temp_Matrix.x=right.x;temp_Matrix.y=right.y;return temp_Matrix;}//----------------------------------------重?载?乘?号?Matrix & operator * (const Matrix & left,const Matrix & right){if(left.y!=right.x){cout<<"\n两¢?个?矩?阵¨®相¨¤乘?错䨪误¨®.";exit(0);}temp_Matrix.init();unsigned i,j,k;for(i=0;i<left.x;i++)for(j=0;j<right.y;j++)for(k=0;k<left.y;k++)temp_Matrix.data[i][j]+=left.data[i][k] * right.data[k][j];temp_Matrix.x=left.x;temp_Matrix.y=right.y;return temp_Matrix;}//-------------------------------------------输º?入¨?矩?阵¨®void Matrix::creat(){cout<<"输º?如¨?行D列¢D式º?:";cout<<"\n行D数ºy:";cin>>x;cout<<"列¢D数ºy:";cin>>y;for(unsigned i=0;i<x;i++){cout<<"输º?入¨?第̨²"<<i+1<<"行D:";for(unsigned j=0;j<y;j++)cin>>data[i][j];}}//----------------------------------------------输º?出?矩?阵¨®void Matrix::show(){unsigned i,j;cout<<"\n\n矩?阵¨®表À¨ª示º?如¨?下?:";for(i=0;i<x;i++){cout<<endl;for(j=0;j<y;j++)cout<<setw(7)<<setiosflags(ios::left)<<data[i][j];}}//----------------------------------用®?Householder矩?阵¨®化¡¥为a实º¦Ì对?称?矩?阵¨®void Householder(Matrix & source){for(i=0;i<source.x-2;i++){#pragma omp parallel for private(k)for(k=0;k<Max_xy;k++){ //初?始º?化¡¥为a0temp_lie_x[k]=0;temp_lie_y[k]=0;temp[k]=0;}for(lenth=0;lenth+i+1<source.x;lenth++) //提¬¨¢取¨?第̨²data[i+1][i]到Ì?data[x-1][i]的Ì?数ºy 据Y存ä?到Ì?temp_lie[Max_xy];temp_lie_x[lenth]=source.data[lenth+i+1][i];for(k=0,s=0;k<lenth;k++) //j为a临¢¨´时º¡À变À?量¢?的Ì?个?数ºy.s+=temp_lie_x[k]*temp_lie_x[k];s=sqrt(s);temp_lie_y[0]=-s;for(k=1;k<lenth;k++)temp_lie_y[k]=0;for(k=0;k<lenth;k++)temp[k]=temp_lie_x[k]-temp_lie_y[k];for(k=0,flag=0;k<lenth;k++) //假¨´如¨?以°?上¦?两¢?个?向¨°量¢?相¨¤等̨¨则¨°退ª?出?,则¨°跳¬?出?以°?进?行D下?一°?次ä?变À?换?if(temp[k]!=0){flag=1;break;}if(flag==0)continue;Matrix part_h,I,x_y; //定¡§义°?Matrix变À?量¢?I.creat_unit(lenth);x_y.x=lenth,x_y.y=1;//对?x_y赋3值¦Ìfor(k=0;k<lenth;k++)x_y.data[k][0]=temp[k];//求¨®x_y的Ì?转Áa置?Matrix zhuanzhi_x_y( x_y ); //拷?贝À¡ä构1造¨¬函¡¥数ºyzhuanzhi_x_y.transpose();s=2.0 / ( x_y.mode() * x_y.mode() );x_y.shucheng(s);temp_Matrix=x_y * zhuanzhi_x_y;part_h=I- x_y*zhuanzhi_x_y;Matrix H;H.creat_unit(source.x);for(m=i+1;m<source.x;m++)for(n=i+1;n<source.y;n++)H.data[m][n]=part_h.data[m-i-1][n-i-1]; //得Ì?到Ì?最Á?后¨®的Ì?Householder矩?阵¨®source=source * H;source=H * source;}for(i=0;i<source.x;i++)for(k=0;k<source.y;k++)if(fabs(source.data[i][k]) < 1e-13)source.data[i][k]=0;}//------------------------------------检¨¬查¨¦是º?否¤?为a实º¦Ì对?称?矩?阵¨®void Matrix::check_shiduichen(){if(x!=y){cout<<"\n\n不?是º?是º?对?称?矩?阵¨®(行D列¢D不?相¨¤等̨¨)\n\n";exit(0);}for(unsigned i=0;i<x;i++)for(unsigned j=0;j<y;j++){if(data[i][j]!=data[j][i]){cout<<"\n\n不?是º?实º¦Ì对?称?矩?阵¨®!(不?对?称?!)\n\n";exit(0);}}}ostream & operator <<(ostream & os,const Matrix & source){unsigned i,j;for(i=0;i<source.x;i++){os<<"\n";for(j=0;j<source.y;j++)os<<setw(10)<<setiosflags(ios::left)<<source.data[i][j]<<"\t";}os<<endl;return os;}void Matrix::set_x(unsigned xx) //设¦¨¨置?行D数ºy{x=xx;}void Matrix::set_y(unsigned yy) //设¦¨¨置?列¢D数ºy{y=yy;}unsigned Matrix::get_x() //得Ì?到Ì?行D数ºy{return x;}unsigned Matrix::get_y() //得Ì?到Ì?列¢D数ºy{return y;}double Matrix::getdata(unsigned i,unsigned j) //定¡§位?得Ì?到Ì?数ºy据Y {return data[i][j];}void Matrix::setdata(unsigned i,unsigned j,double source){data[i][j]=source;if(x<i) x=i;if(y<j) y=j;}void Matrix::creat_unit(unsigned lenth) //生¦¨²成¨¦i行D单Ì£¤位?矩?阵¨®{init();x=y=lenth;for(unsigned i=0;i<lenth;i++)data[i][i]=1;}void Matrix::shucheng(double changshu) //数ºy乘?运?算?加¨®入¨?并¡é行D语®?句? {int i,j;omp_set_num_threads(3);#pragma omp parallel forfor(i=0;i<x;i++)for(j=0;j<y;j++)data[i][j]*=changshu;}void Matrix::sturm(){double s,r,maxhang,a,b;unsigned i,j,m;for(i=0,maxhang=0;i<x;i++){ for( s=0,j=0;j<y;j++)s+=fabs(data[i][j]);if(s>maxhang)maxhang=s;}a=-maxhang;b=maxhang;m=sturm_s(a)-sturm_s(b);for(i=1;i<=m;i++){a=-maxhang;b=maxhang;do{r=0.5*(a+b);if(sturm_s(r)>=i)a=r;elseb=r;}while(fabs(a-b)>1e-11);cout<<"\n特¬?征¡Â值¦Ì"<<i<<": "<</*setiosflags(ios::left)<<setw(10)<<*/setprecision(10) <<setiosflags(ios::fixed)<<0.5*(a+b);}}unsigned Matrix::sturm_s(double r){double p[Max_xy+1];int temp[Max_xy+1];unsigned m,i;p[0]=1;p[1]=data[0][0]-r;for(i=2;i<=x;i++)p[i]=(data[i-1][i-1]-r)*p[i-1]-data[i-2][i-1]*data[i-2][i-1]*p[i-2];temp[0]=1;for(i=1;i<=x;i++)if(p[i]>1e-14)temp[i]=1;else if(p[i]<-1e-14)temp[i]=-1;elsetemp[i]=temp[i-1];for(i=1,m=0;i<=x;i++)if(temp[i]+temp[i-1]!=0)m++;return m;}int _tmain(int argc, _TCHAR* argv[]){double begin,end,time;begin=(double)clock()/(double)CLK_TCK;Matrix a;a.creat();cout<<"输º?入¨?的Ì?矩?阵¨®为a:";cout<<a;a.check_shiduichen();Householder(a);cout<<"用®?Householder化¡¥为a实º¦Ì对?称?矩?阵¨®为a:";cout<<a;a.sturm();cout<<endl;end=(double)clock()/(double)CLK_TCK;time=end-begin;cout<<"时º¡À间?是º?:êo";cout<<time;return 0;}程序运行结果:四、实验结果分析(运行过程中出现的问题、如何解决的;实验过程中的经验及教训)并行化结果展示:3*3维矩阵串行程序时间:t1=9.81ms并行程序时间:t2=7.612ms加速比=20.81ms/7.612=2.733并行化结果展示:10*10维矩阵串行程序时间:t1=144.581ms并行程序时间:t2=109.699ms加速比=144.581ms/109.699ms=1.317并行化结果展示:15*15维矩阵串行程序时间:t1=365.461ms并行程序时间:t2=290.316ms加速比=365.461ms/290.316ms=1.255体现了并行的优越性。

基于多核CPU的并行体绘制算法应用研究的开题报告

基于多核CPU的并行体绘制算法应用研究的开题报告

基于多核CPU的并行体绘制算法应用研究的开题报告一、选题背景随着计算机硬件发展的趋势,多核CPU已经成为了现代计算机的主流配置。

另一方面,计算机图形学也在不断地发展,对于体绘制算法提出了更高的要求。

因此,基于多核CPU的并行体绘制算法研究和应用具有重要的意义和价值。

二、研究目的本研究旨在探究基于多核CPU的并行体绘制算法,并对算法进行优化,以提高绘制效率和图形质量,实现在大规模数据集上的快速高效绘制。

三、研究内容1. 多核CPU并行计算原理和实现方式的调研分析;2. 基于多核CPU并行计算的体绘制算法研究和设计;3. 对算法进行优化,提高绘制效率和图形质量;4. 在大规模数据集上进行实验验证。

四、研究方法1. 文献资料法:对现有的多核CPU并行计算和体绘制算法的相关研究资料进行调研分析;2. 理论分析法:对多核CPU并行计算和体绘制算法的原理和实现方式进行深入理论分析;3. 实验验证法:在大规模数据集上进行实验验证,对所设计的算法进行评测和对比分析。

五、预期成果1. 基于多核CPU的并行体绘制算法;2. 绘制效率和图形质量的优化方案;3. 在大规模数据集上的实验结果和分析。

六、可行性分析本研究的主要内容是对现有的体绘制算法进行修改和优化,使其适合多核CPU并行计算,因此具有较高的可行性。

通过文献调研和实验验证,对多核CPU并行计算和体绘制算法的优化算法和实现方式进行探究,有望得出一些有价值的研究结论和实践经验。

七、研究进度安排本研究的时间计划为两年,按以下安排进行:第一年:1. 调研研究多核CPU并行计算原理和实现方式;2. 研究现有体绘制算法并对其进行分析;3. 设计并实现基于多核CPU的并行体绘制算法。

第二年:1. 优化算法,提高绘制效率和图形质量;2. 在大规模数据集上进行实验验证;3. 撰写毕业论文和发表学术论文。

八、参考文献1. 孙隆基. 大规模数据可视化: 算法、设计与应用[M]. 北京: 清华大学出版社, 2010.2. Christophe Lino, Olivier Nocent, Marc Daniel. A Scalable Strategy for Interactive Multiresolution Iso-Surface Visualization[C]// IEEESymposium on Parallel and Large-Data Visualization and Graphics. Berlin, Germany, 2013.3. Hua-Ching Chen, Yi-Jen Chiang, Chi-Hoon Lee, et al. A Parallel Isosurface Extraction Method with Graphics Processing Units and Multi-Core CPUs[C]// IEEE Third International Conference on Emerging Security Technologies. Lisbon, Portugal, 2012.。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
}
分块数为10000
线程数2
线程数4
线程数6
线程数8
线程数10
线程数12
线程数14
线程数16
固定线程数目为4,改变分块数目(从100到10000000)
蒙特卡罗法
1.传统单线程代码
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
intmain(intargc,char* argv[])
//随机种子
srand((unsigned)time(NULL));
// 多线程初始化
HANDLE *hThread = NULL;
hThread = (HANDLE *)malloc(sizeof(HANDLE) * num_thread);
InitializeCriticalSection(&cs);// 临界区初始化
system("Pause");
return0;
}
随机数产生次数max 10000
随机数产生次数max 100000
随机数产生次数max 1000000
随机数产生次数max 10000000
3.OpenMP编程代码
#include<stdio.h>
{
longlongmax=10000000;//max可以修改?
longlongi,count=0;
doublex,y,bulk,starttime,endtime;
time_t t;
starttime=clock();// 产生以当前时间开始的随机种子
srand((unsigned) time(&t));
如图所示,正方形边长为1,左下顶点与原点重合,两边分别与x轴重合。曲线为1/4圆弧,圆心位于原点,与正方形左下定点重合,半径为1。正方形面积S1=1,圆弧内面积S2=/4。算法模拟大量点随机落在此正方形区域内,落在圆弧内的点的数量(n2)与点的总数(n1)的比例与面积成正比关系。即
系统硬件环境:通过CPU-Z获取本机CPU型号,二级cache容量,处理器内核数和逻辑线程数等信息
inti;
doublex, sum=0, pi=0.0;
doublestep = 1.0/(double) num_steps;
omp_set_num_threads(NUM_THREADS);
#pragmaomp parallelforprivate(x) reduction(+:sum)
for(i=0;i<num_steps;i++)
//多线程结束后计算PI值
PI = hit_times / rand_times * 4;
//记录结束时间
clock_t end_time = clock();
DeleteCriticalSection(&cs);// 注销临界区
printf("PI = %lf\n", PI);
printf("time = %d\n", end_time - start_time);
printf("Pi = %f \n", pi);
printf("time = %f \n", endtime-starttime);
return0;
}
块数1000000
块数10000000
块数10000000
块数为100000000
2. WinAPI多线程编程代码
#include<windows.h>
doublestep;
usingnamespacestd;
intmain(intargc,char* argv[])
{
inti;
doublex, pi, starttime,endtime,sum = 0.0;
step = 1.0/(double) num_steps;
time_t t;
starttime=clock();
for(i=0;i<max;i++)
{
x=rand();
x=x/32767;
y=rand();
y=y/32767;
if((x*x+y*y)<=1)
count++;
}
bulk=4*(double(count)/max);
endtime= clock();
printf("max = %d\n",max);
使用三种编程方法实现积分法或蒙特卡洛法计算pi值(选择实现其中一种,建议蒙特卡洛法)
串行方法
Windows环境多线程编程
Windows环境OpenMP库并行编程
积分法计算pi值的基本原理
因此可以用上述公式来计算π的值。
蒙特卡罗法计算pi值的基本原理
蒙特卡洛算法可理解为通过大量实验,模拟实际行为,来收集统计数据。本例中,算法随机产生一系列点,模拟这些点落在如下图所示的正方形区域内的情况。其几何解释如下
{
x = (i+0.5)*step;
sum += 4.0/(1.0+x*x);
}
WaitForMultipleObjects(NUM_THREADS,hthread,TRUE,INFINITE);
DeleteCriticalSection(&g);
pi=step*sum;
QueryPerformanceCounter(&temp);
//记录开始时间
clock_t start_time = clock();
// 多线程创建
for(inti = 0; i < num_thread; i++)
hThread[i] = CreateThread(NULL, 0, calc_pi, NULL, 0, NULL);
// 等待所有进程结束
WaitForMultipleObjects(num_thread, hThread, TRUE, INFINITE);
操作系统:winxp 32位(学校机房电脑)
开发工具:Visual studio 2010
系统硬件环境
积分法
1.传统单线程代码
#include<windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
staticlongnum_steps = 1000000000;//块数可以修改
{
x=(i+0.5)*step;
sum1+=4.0/(1.0+x*x);
}
EnterCriticalSection(&g);
sum+=sum1;
LeaveCriticalSection(&g);
return0;
}
voidmain()
{
cout<<"输入分块的数目:";
cin>>num_step;
LARGE_INTEGER temp;
CRITICAL_SECTION g;
DWORD WINAPI threadFunc(LPVOID pParam)
{
intnum=*((int*)pParam);
doublex,sum1=0;
step=1.0/(double)num_step;
for(inti=num;i<num_step;i+=Threadnum)
for(DWORD i = 0; i < rand_times / num_thread; i++){
doublex = rand() /double(RAND_MAX);//随机生成一个[0,1]之间的一个数
doubley = rand() /double(RAND_MAX);
EnterCriticalSection(&cs);// 进入临界区
printf("Pi = %f \n", bulk);
printf("time = %f \n", endtime-starttime);
return0;
}
改变随机产生数max
2. WinAPI多线程编程代码
#include"windows.h"
#include"time.h"
#include<stdio.h>
srand((unsigned) time(&t));
for(i=0;i< num_steps; i++)
{
x = (i+0.5)*step;
sum = sum + 4.0/(1.0+x*x);
}
pi = step * sum;
endtime= clock();
printf("块数 = %d \n", num_steps);
intrand_times = 0;//随机次数
intnum_thread = 2;//线程个数
doublePI = 0;//估计PI值
doublehit_times = 0;//击中单位圆的次数
CRITICAL_SECTION cs;//创建临界区
DWORD WINAPI calc_pi(LPVOID arg){
HANDLE hthread[Threadnum];
InitializeCriticalSection(&g);
相关文档
最新文档