1. 程式人生 > >OpenCL的多GPU和多核CPU異構計算--2

OpenCL的多GPU和多核CPU異構計算--2

        本文主要探究OpenCL的GPU和多核CPU的異構計算問題,主要簡要闡述了什麼是OpenCL異構計算,講述CPU和GPU各自的特點,並且把他們結合起來做異構計算的前景。然後具體講述在高效能實驗室Linux工作站上如何搭建多GPU和多核CPU異構OpenCL環境。最後用實驗驗證了所安裝的OpenCL異構計算環境能夠正常工作,說明什麼是OpenCL的多GPU與多核CPU異構環境的platform,device等。

用兩篇文章介紹以上內容,轉載請註明原作者及地址!

3 測試OpenCL程式

3.1 獲取PlatForm資訊

本實驗主要是用來顯示platform的個數,各個platform

的名稱,id號。

  • 實驗目的:

  • 1ArchLinuxRedHatLinux兩臺工作站上的platform個數

  • 2各個platformAMDNVIDIAINTEL等)的id號,是固定的,還是是隨機的,個人認為是固定,每個品牌一個ID.

  • 程式的主要3步驟,詳情見附件三的原始碼!

/*1步,取得platform數量(AMDNVIDIAIntel等)*/

/*2步,獲得各個platformID號,假設有多個platform(經常的情況是隻有一個)*/

/*3步,輸出各個platformID號,名稱,假設有多個platform*/

  • 編譯執行測試

編譯:

make

測試:

make test

輸出顯示:

  • 高效能實驗室workstation-0Arch Linux 64位作業系統:

  • 1.Arch Linux 64位作業系統

  • 2.64AMD處理器,32G記憶體,500G硬碟,雙顯示卡

  • 3.顯示卡1:華碩HD6870AMDGPU晶片:ATIRadeon HD 6870

  • 4.顯示卡2:華碩HD6870AMDGPU晶片:ATIRadeon HD 6870

NVIDIA GPU

num of platform: 1
ID: 19412080			//(每次執行的id號都不一樣)
PLATFORM: NVIDIA Corpration
  • 高效能實驗室workstation-1Redhat EL 6.1 64位作業系統:

  • 1Redhat EL 6.1 64位作業系統

  • 264AMD處理器,32G記憶體,500G硬碟,雙顯示卡

  • 3顯示卡1:華碩HD6870AMDGPU晶片:ATIRadeon HD 6870

  • 4顯示卡2NVIDIAQuadro FX 4800

AMD GPU

num of platform: 1
ID: 1307533408		//(每次執行的id號都不一樣)
PLATFORM: Advanced Micro Devices, Inc.
  • 實驗結論:

  • 1ArchLinuxRedHatLinux兩臺工作站上的platform個數都是1

    • 對應於ArchLinux工作站上是NVIDIA顯示卡!

    • RedHatLinux工作站上是AMD顯示卡(包不包含AMDCPU?有待下面第二個實驗測試)

  • 2各個platformAMDNVIDIAINTEL等)的id號,不是之前沒實驗前所想象的是固定的,實際上是隨機的!

3.2 獲取Device資訊

  • 實驗目的:

  • 1測試ArchLinuxRedHatLinux兩臺工作站上的device個數(GPU+CPU

  • 2嘗試能不能使用CPU作為deviceGPU已經證實可以使用)

  • 程式的主要步驟如下,詳情見附件四的原始碼!

/*1步,獲得platform資訊*/

/*2步,獲得device資訊*/

//1獲得device數量,對應於GPU,或CPU個數

//2獲得各個deviceid

//3輸出deviceid,個數,以及名稱

  • 編譯執行測試

編譯:

make

測試:

make test

輸出顯示:

  • 高效能實驗室workstation-0Arch Linux 64位作業系統:

  • 1.Arch Linux 64位作業系統

  • 已裝NVIDIASDKGPU用),沒裝AMDSDKCPU用)

  • 2.64AMD處理器,32G記憶體,500G硬碟,雙顯示卡

  • 3.顯示卡1:華碩HD6870AMDGPU晶片:ATIRadeon HD 6870

  • 4.顯示卡2:華碩HD6870AMDGPU晶片:ATIRadeon HD 6870

1 NVIDIA-GPU

platform_id:27686000
num_of_platforms:1
platform_name: NVIDIA Corporation

num_of_devices:2					//NVIDIA-GPU的device數量為2
device_id[0]: 27686192
device_name: NVIDIA Corporation	//NVIDIA-GPU的device名稱
device_id[1]: 27686304
device_name: NVIDIA Corporation

2 NVIDIA-CPU

platform_id:26154096
num_of_platforms:1
platform_name: NVIDIA Corporation

Unable to get device_id				//NVIDIA-CPU的device找不到,
 								//因為AMD CPU沒安裝AMD SDK
  • 高效能實驗室workstation-1Redhat EL 6.1 64位作業系統:

  • 1Redhat EL 6.1 64位作業系統

  • 已裝AMDSDKGPU+CPU用),沒裝NVIDIASDKGPU用)

  • 264AMD處理器,32G記憶體,500G硬碟,雙顯示卡

  • 3顯示卡1:華碩HD6870AMDGPU晶片:ATIRadeon HD 6870

  • 4顯示卡2NVIDIAQuadro FX 4800

3 AMD-GPU

platform_id:27686000
num_of_platforms:1
platform_name: Advanced Micro Devices, Inc.

num_of_devices:1					//AMD-GPU的device數量為1
device_id[0]: 27686192
device_name: Advanced Micro Devices, Inc.	//AMD-GPU device名稱,有別於CPU名稱

4 AMD-CPU

platform_id:27686000
num_of_platforms:1
platform_name: Advanced Micro Devices, Inc.

num_of_devices:1					//AMD-CPU的device數量也為1
device_id[0]: 27686192
device_name: AuthenticAMD		//AMD-CPU的device名稱,有別於GPU的名稱
  • 博士屋workstation-2Redhat EL 6.1 32位作業系統:

  • 1Redhat EL 6.1 32位作業系統

  • AMDSDKCPU用),沒裝IntelSDKCPU用)

  • 2處理器Intel(R)Core(TM) i3 CPU550@ 3.20GHz4G記憶體,1T硬碟,整合顯示卡

5 Intel-CPU

platform_id:37407616
num_of_platforms:1
platform_name: Advanced Micro Devices, Inc.	//因為在32Bit Linux,Intel處理器上
  										//用的是AMD SDK,而非Intel SDK

num_of_devices:1
device_id[0]: 141832504
device_name: GenuineIntel					//Intel 裝置
  • 實驗結論:

  • 1ArchLinuxRedHatLinux兩臺工作站上的GPUdevice個數分別是21

    • 對應於ArchLinux工作站上有兩個NVIDIA顯示卡,可以獲得2GPUdevice

    • RedHatLinux工作站上有一個AMD顯示卡,可以獲得1GPUdevice!(其實上面還有個NVIDIA顯示卡,只不過還沒裝驅動等,不能工作,目前)!

  • 2ArchLinuxRedHatLinux兩臺工作站上的CPUdevice個數分別是01

    • 對應於ArchLinux工作站無法獲得CPUdevice,因為只裝了NVIDIAopenCL,而沒安裝AMDSDKAMDSDK可以在GPU+CPU上執行)!

    • RedHatLinux工作站可以獲得1CPUdevice,因為安裝了AMDSDKAMDSDK可以在GPU+CPU上執行)!

附件一:NVIDIAMakefile模板

SRCNAME= PlatForm

$(SRCNAME): $(SRCNAME).cpp
		g++ -o $(SRCNAME)  $(SRCNAME).cpp -lOpenCL
clean:
		rm $(SRCNAME)
test:
		./$(SRCNAME)


附件二:AMDMakefile模板

SRCNAME = PlatForm

$(SRCNAME): $(SRCNAME).cpp
		g++  -o  $(SRCNAME)  $(SRCNAME).cpp \
-Wpointer-arith  -Wfloat-equal  -g3  -ffor-scope \
-I  /opt/AMDAPP/samples/opencl/SDKUtil/include \
-I  "/include" \
-I  /opt/AMDAPP/include \
-lpthread  -ldl  -lSDKUtil  -lOpenCL -lglut -lGLEW \
-L/usr/X11R6/lib \
-L/opt/AMDAPP/lib/x86_64 \
-L/opt/AMDAPP/TempSDKUtil/lib/x86_64 \
-L"/lib/x86_64"
		rm -rvf $(SRCNAME).o
clean:
		rm -rvf $(SRCNAME)
test:
		./$(SRCNAME)


附件三:獲取PlatForm的資訊程式原始碼

#include<stdio.h>
#include<CL/cl.h>


int main(void)
{

/*第1步,取得platform數量(AMD,NVIDIA,Intel等)*/
	cl_uint num_of_platforms=0;
        
	if (clGetPlatformIDs(0, NULL, &num_of_platforms)!= CL_SUCCESS){
		printf("Error: Getting Platform.\n");
		return 1;
	}

	printf("num of platform: %d\n", num_of_platforms);

/*第2步,獲得各個platform的ID號,假設有多個platform(經常的情況是隻有一個)*/
	if (num_of_platforms > 0){
		cl_platform_id *platform_id =(cl_platform_id *)malloc( num_of_platforms * sizeof(cl_platform_id));
		if (clGetPlatformIDs(num_of_platforms, platform_id, NULL)!= CL_SUCCESS){
			printf("Error: Geting Platform IDs.\n");
			return 1;
		}
/*第3步,輸出各個platform的ID號,名稱,假設有多個platform(經常的情況是隻有一個)*/
		char pbuff[50];
		for(int i=0; i< num_of_platforms; ++i){
			clGetPlatformInfo(platform_id[i], CL_PLATFORM_VENDOR, sizeof(pbuff), pbuff, NULL);
			printf("ID: %d\nPLATFORM: %s\n",platform_id[i],pbuff);
		}
	}

	return 0;
}


附件四:獲取Device資訊的程式原始碼

#include<stdio.h>
#include<CL/cl.h>

int main(void)
{
/*第1步,獲得platform資訊*/

//因為第一個實驗已經知道,兩臺工作站上的platform個數都是1,所以沒必要在測試platform個數了
	cl_uint num_of_platforms=0;
	cl_platform_id platform_id;
	if (clGetPlatformIDs(1, &platform_id, &num_of_platforms)!= CL_SUCCESS){
		printf("Unable to get platform_id\n");
		return 1;
	}
//輸出platform的id,個數
	printf("platform_id:%d\nnum_of_platforms:%d\n", platform_id, num_of_platforms);
//輸出platform名稱
	char pbuff[50];
	clGetPlatformInfo(platform_id, CL_PLATFORM_VENDOR, sizeof(pbuff), pbuff, NULL);
	printf("platform_name: %s\n\n", pbuff);

/*第2步,獲得device資訊*/

//1獲得device數量,對應於GPU,或CPU個數
	cl_uint num_of_devices=0;
	//if (clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_CPU, 0, NULL, &num_of_devices) != CL_SUCCESS){
	if (clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, 0, NULL, &num_of_devices) != CL_SUCCESS){
		printf("Unable to get device_id\n");
		return 1;
	}
	printf("num_of_devices:%d\n", num_of_devices);

	if (num_of_devices > 0){
//2獲得各個device的id號
		cl_device_id *device_id = (cl_device_id *)malloc( num_of_devices * sizeof(cl_device_id));
		//if (clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_CPU, num_of_devices, device_id, NULL) != CL_SUCCESS){
		if (clGetDeviceIDs(platform_id, CL_DEVICE_TYPE_GPU, num_of_devices, device_id, NULL) != CL_SUCCESS){
			printf("Unable to get device_id\n");
			return 1;
		}
//3輸出device的id,個數,以及名稱
		char pbuff[50];
		for(int i=0; i< num_of_devices; ++i){
			clGetDeviceInfo(device_id[i], CL_DEVICE_VENDOR, sizeof(pbuff), pbuff, NULL);
			printf("device_id[%d]: %d\ndevice_name: %s\n", i, device_id[i], pbuff);
		}
	}

	return 0;
}


原創作品,轉載請註明作者和出處! by 飛鴻驚雪