Commit 48fc8d8f by 10382

📝 1st Homework Finished!

parent 89064957
##Cupy和numpy的比较
# Cupy和numpy的比较
##
Cupy是使用NVIDIA CUDA核心进行加速运算,因为GPU上有好多CUDA核心,相比CPU可以同时并行更多的线程,因此可以大大提高运算速度,当数据量达到千万级时,用cupy会大大增加运算速度。
该作业我主要是验证以上观点,通过比较cupy和numpy在不同矩阵大小下进行加法和乘法的运算时间来验证该观点。(目前 cupy 的环境报错问题还没解决,还在解决中,解决完成后进行后序实验。)
\ No newline at end of file
该作业我主要是验证以上观点,通过比较`cupy``numpy`在不同矩阵大小下进行加法和乘法的运算时间来验证该观点。
## 实验
### 加法
从 1x1 的大小开始生成随机数矩阵,每次对矩阵的长和宽分别 x2 以扩大矩阵,每个矩阵大小下分别用 `cupy``numpy` 分别进行十次矩阵相加运算,最后比较他们的平均运算时间(不包括矩阵生成,只包括运算)。得到的结果如下,
```
目前矩阵大小为1x1=1
cupy 加法的平均执行时间是 0.000059 s
numpy 加法的平均执行时间是 0.000004 s
目前矩阵大小为2x2=4
cupy 加法的平均执行时间是 0.000011 s
numpy 加法的平均执行时间是 0.000003 s
目前矩阵大小为4x4=16
cupy 加法的平均执行时间是 0.000012 s
numpy 加法的平均执行时间是 0.000003 s
目前矩阵大小为8x8=64
cupy 加法的平均执行时间是 0.000012 s
numpy 加法的平均执行时间是 0.000005 s
目前矩阵大小为16x16=256
cupy 加法的平均执行时间是 0.000013 s
numpy 加法的平均执行时间是 0.000004 s
目前矩阵大小为32x32=1024
cupy 加法的平均执行时间是 0.000014 s
numpy 加法的平均执行时间是 0.000005 s
目前矩阵大小为64x64=4096
cupy 加法的平均执行时间是 0.000015 s
numpy 加法的平均执行时间是 0.000006 s
目前矩阵大小为128x128=16384
cupy 加法的平均执行时间是 0.000014 s
numpy 加法的平均执行时间是 0.000013 s
目前矩阵大小为256x256=65536
cupy 加法的平均执行时间是 0.000014 s
numpy 加法的平均执行时间是 0.000039 s
目前矩阵大小为512x512=262144
cupy 加法的平均执行时间是 0.000023 s
numpy 加法的平均执行时间是 0.000195 s
目前矩阵大小为1024x1024=1048576
cupy 加法的平均执行时间是 0.000025 s
numpy 加法的平均执行时间是 0.001306 s
目前矩阵大小为2048x2048=4194304
cupy 加法的平均执行时间是 0.000031 s
numpy 加法的平均执行时间是 0.010306 s
目前矩阵大小为4096x4096=16777216
cupy 加法的平均执行时间是 0.000069 s
numpy 加法的平均执行时间是 0.036332 s
目前矩阵大小为8192x8192=67108864
cupy 加法的平均执行时间是 0.000131 s
numpy 加法的平均执行时间是 0.140579 s
目前矩阵大小为16384x16384=268435456
cupy 加法的平均执行时间是 0.003624 s
numpy 加法的平均执行时间是 0.565655 s
......(显存爆了)......
```
可以看到一开始用小矩阵进行加法运算时,`cupy` 运算速度时不及 `numpy` 的,当矩阵大小达到 128x128 时,其速度相近了。当矩阵大小更大时,`cupy` 的优势体现出来了,`cupy` 的运算速度比 `numpy` 快了百倍。
### 乘法
乘法的测试方法也和加法一样,只是 `add(x, y)` 替换成了 `multiply(x, y)`。具体结果如下,
```
目前矩阵大小为1x1=1
cupy 乘法的平均执行时间是 0.000060 s
numpy 乘法的平均执行时间是 0.000004 s
目前矩阵大小为2x2=4
cupy 乘法的平均执行时间是 0.000012 s
numpy 乘法的平均执行时间是 0.000003 s
目前矩阵大小为4x4=16
cupy 乘法的平均执行时间是 0.000012 s
numpy 乘法的平均执行时间是 0.000003 s
目前矩阵大小为8x8=64
cupy 乘法的平均执行时间是 0.000012 s
numpy 乘法的平均执行时间是 0.000003 s
目前矩阵大小为16x16=256
cupy 乘法的平均执行时间是 0.000013 s
numpy 乘法的平均执行时间是 0.000004 s
目前矩阵大小为32x32=1024
cupy 乘法的平均执行时间是 0.000013 s
numpy 乘法的平均执行时间是 0.000004 s
目前矩阵大小为64x64=4096
cupy 乘法的平均执行时间是 0.000013 s
numpy 乘法的平均执行时间是 0.000006 s
目前矩阵大小为128x128=16384
cupy 乘法的平均执行时间是 0.000013 s
numpy 乘法的平均执行时间是 0.000014 s
目前矩阵大小为256x256=65536
cupy 乘法的平均执行时间是 0.000014 s
numpy 乘法的平均执行时间是 0.000043 s
目前矩阵大小为512x512=262144
cupy 乘法的平均执行时间是 0.000021 s
numpy 乘法的平均执行时间是 0.000189 s
目前矩阵大小为1024x1024=1048576
cupy 乘法的平均执行时间是 0.000025 s
numpy 乘法的平均执行时间是 0.001378 s
目前矩阵大小为2048x2048=4194304
cupy 乘法的平均执行时间是 0.000029 s
numpy 乘法的平均执行时间是 0.010370 s
目前矩阵大小为4096x4096=16777216
cupy 乘法的平均执行时间是 0.000066 s
numpy 乘法的平均执行时间是 0.041170 s
目前矩阵大小为8192x8192=67108864
cupy 乘法的平均执行时间是 0.000127 s
numpy 乘法的平均执行时间是 0.161565 s
目前矩阵大小为16384x16384=268435456
cupy 乘法的平均执行时间是 0.000871 s
numpy 乘法的平均执行时间是 0.651580 s
......(显存爆了)......
```
得出的结论也和加法相同,但我注意到 `cupy` 在 16384x16384 量级的乘法运算上要比加法运算快 4 倍,这是什么原因呢?照理来说,两个运算时间应该相近才对,于是我又在该大小的矩阵乘法下运行了100次加法和乘法,结果如下,
```
目前矩阵大小为16384x16384=268435456
cupy 加法的平均执行时间是 0.001242 s
numpy 加法的平均执行时间是 0.577567 s
cupy 乘法的平均执行时间是 0.001297 s
numpy 乘法的平均执行时间是 0.669743 s
```
可能是因为10次样本太少,导致统计出现了一些偏差,在100次下,`cupy` 乘法和加法的运算时间相近。
## 结论
当数据量大于万级(128x128=16384)时,`cupy` 的运算速度就会超越 `numpy`;当数据量大于百万级(1024x1024=1048576)时,`cupy` 的运算速度远超 `numpy`
## 附录
具体代码:
- [hello_cupy.py](./hello_cupy.py)
\ No newline at end of file
import time
import cupy as cp
import numpy as np
def timer(func):
def wrapper(*args, **kwargs):
time_start = time.time()
func(*args, **kwargs)
time_spent = time.time() - time_start
# print("%s 的执行时间是 %f s" % (func.__name__, time.time() - time_start))
return time_spent
return wrapper
@timer
def cp_add(a, b):
# print(cp.add(a, b))
return cp.add(a, b)
@timer
def np_add(a, b):
return np.add(a, b)
@timer
def cp_prod(a, b):
# print(cp.add(a, b))
return cp.multiply(a, b)
@timer
def np_prod(a, b):
return np.multiply(a, b)
if __name__ == '__main__':
# 不同大小的矩阵在 numpy 和 cupy 上进行验证
len = 1
# while len <= 10:
while len <= 1e15:
cp_time_list = []
np_time_list = []
print(u"目前矩阵大小为%sx%s=%s" % (len, len, len*len))
for i in range(10):
x = cp.random.randint(0, 10, size=(len, len))
cp_time_list.append(cp_add(x, x))
# cp_time_list.append(cp_prod(x, x))
x = cp.asnumpy(x)
np_time_list.append(np_add(x, x))
# np_time_list.append(np_prod(x, x))
print("cupy 加法的平均执行时间是 %f s" % (np.mean(cp_time_list)))
print("numpy 加法的平均执行时间是 %f s" % (np.mean(np_time_list)))
len *= 2
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment