您的位置:首页 > 运维架构

OpenCL的多GPU和多核CPU异构计算--2

2012-02-20 12:50 260 查看
        本文主要探究OpenCL的GPU和多核CPU的异构计算问题,主要简要阐述了什么是OpenCL异构计算,讲述CPU和GPU各自的特点,并且把他们结合起来做异构计算的前景。然后具体讲述在高性能实验室Linux工作站上如何搭建多GPU和多核CPU异构OpenCL环境。最后用实验验证了所安装的OpenCL异构计算环境能够正常工作,说明什么是OpenCL的多GPU与多核CPU异构环境的platform,device等。

用两篇文章介绍以上内容,转载请注明原作者及地址!

3 测试OpenCL程序

3.1 获取PlatForm信息

本实验主要是用来显示platform的个数,各个platform的名称,id号。

实验目的:

1ArchLinux和RedHatLinux两台工作站上的platform个数

2各个platform(AMD,NVIDIA,INTEL等)的id号,是固定的,还是是随机的,个人认为是固定,每个品牌一个ID.

程序的主要3步骤,详情见附件三的源代码!

/*第1步,取得platform数量(AMD,NVIDIA,Intel等)*/
/*第2步,获得各个platform的ID号,假设有多个platform(经常的情况是只有一个)*/
/*第3步,输出各个platform的ID号,名称,假设有多个platform*/

编译运行测试

编译:

make


测试:

make test


输出显示:

高性能实验室workstation-0Arch Linux 64位操作系统:

1.Arch Linux 64位操作系统

2.64位AMD处理器,32G内存,500G硬盘,双显卡

3.显卡1:华硕HD6870,AMD的GPU芯片:ATIRadeon
HD 6870

4.显卡2:华硕HD6870,AMD的GPU芯片: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位操作系统

264位AMD处理器,32G内存,500G硬盘,双显卡

3显卡1:华硕HD6870,AMD的GPU芯片:ATIRadeon
HD 6870

4显卡2:NVIDIAQuadro
FX 4800

AMD GPU

num of platform: 1
ID: 1307533408		//(每次运行的id号都不一样)
PLATFORM: Advanced Micro Devices, Inc.


实验结论:

1ArchLinux和RedHatLinux两台工作站上的platform个数都是1!

对应于ArchLinux工作站上是NVIDIA显卡!

RedHatLinux工作站上是AMD显卡(包不包含AMDCPU?有待下面第二个实验测试)

2各个platform(AMD,NVIDIA,INTEL等)的id号,不是之前没实验前所想象的是固定的,实际上是随机的!

3.2 获取Device信息

实验目的:

1测试ArchLinux和RedHatLinux两台工作站上的device个数(GPU+CPU)

2尝试能不能使用CPU作为device(GPU已经证实可以使用)

程序的主要步骤如下,详情见附件四的源代码!

/*第1步,获得platform信息*/
/*第2步,获得device信息*/
//1获得device数量,对应于GPU,或CPU个数
//2获得各个device的id号
//3输出device的id,个数,以及名称

编译运行测试

编译:

make


测试:

make test


输出显示:

高性能实验室workstation-0Arch Linux 64位操作系统:

1.Arch Linux 64位操作系统

已装NVIDIASDK(GPU用),没装AMDSDK(CPU用)

2.64位AMD处理器,32G内存,500G硬盘,双显卡

3.显卡1:华硕HD6870,AMD的GPU芯片:ATIRadeon
HD 6870

4.显卡2:华硕HD6870,AMD的GPU芯片: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位操作系统

已装AMDSDK(GPU+CPU用),没装NVIDIASDK(GPU用)

264位AMD处理器,32G内存,500G硬盘,双显卡

3显卡1:华硕HD6870,AMD的GPU芯片:ATIRadeon
HD 6870

4显卡2:NVIDIAQuadro
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位操作系统

AMDSDK(CPU用),没装IntelSDK(CPU用)

2处理器Intel(R)Core(TM) i3 CPU550@
3.20GHz,4G内存,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 设备


实验结论:

1ArchLinux和RedHatLinux两台工作站上的GPUdevice个数分别是2,1!

对应于ArchLinux工作站上有两个NVIDIA显卡,可以获得2个GPUdevice!

RedHatLinux工作站上有一个AMD显卡,可以获得1个GPUdevice!(其实上面还有个NVIDIA显卡,只不过还没装驱动等,不能工作,目前)!

2ArchLinux和RedHatLinux两台工作站上的CPUdevice个数分别是0,1!

对应于ArchLinux工作站无法获得CPUdevice,因为只装了NVIDIA的openCL,而没安装AMDSDK(AMDSDK可以在GPU+CPU上运行)!

RedHatLinux工作站可以获得1个CPUdevice,因为安装了AMDSDK(AMDSDK可以在GPU+CPU上运行)!

附件一:NVIDIA的Makefile模板

SRCNAME= PlatForm

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


附件二:AMD的Makefile模板

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 飞鸿惊雪
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息