扩展库pyopencl使得可以在Python中调用OpenCL的并行计算API。OpenCL(Open Computing Language)是跨平台的并行编程标准,可以运行在个人电脑、服务器、移动终端以及嵌入式系统等多种平台,既可以运行在CPU上又可以运行于GPU上,大幅度提高了各类应用中的数据处理速度,包括游戏、娱乐、医学软件以及科学计算等等。
import numpy as np
import pyopencl as cl
import pyopencl.array
from pyopencl.elementwise import ElementwiseKernel
#判断素数的C语言版GPU代码
isPrime = ElementwiseKernel(ctx,
'long *a_g, long *b_g, long *res_g',
'''
int j;
for(j=2; j<b_g[i]; j++)
{
if(a_g[i]%j == 0)
{
break;
}
}
if(j >= b_g[i])
{
res_g[i] = a_g[i];
}''',
'isPrime'
)
#定义待测数值范围,和每次处理的数字数量
end = 100000000
start_end = range(2, end)
size = 1000
result = 0
ctx = cl.create_some_context()
queue = cl.CommandQueue(ctx)
#对指定范围内的数字进行分批处理
for i in range(end//size + 1):
startN = i * size
#本次要处理的数字范围
a_np = np.array(start_end[startN: startN+size]).astype(np.int64)
#b_np里的数字是a_np中数字的平方根取整后加1
b_np = np.array(list(map(lambda x: int(x**0.5)+1, a_np))).astype(np.int64)
#把数据写入GPU
a_g = cl.array.to_device(queue, a_np)
b_g = cl.array.to_device(queue, b_np)
res_g = cl.array.zeros_like(a_g)
#批量判断
isPrime(a_g, b_g, res_g)
t = set(filter(None, res_g.get()))
#记录本批数字中素数的个数
result += len(t)
print(result)