- 本次测试矩阵乘法未作分块优化。
- 未使用cuda测试。
- 采用微秒级的计时器。
- 分别对16阶方矩阵到4048阶方阵采用如下方式做乘法计算,统计结果。
1、C++Amp(GPU),
2、C++PPL(多线程16核),
3、SSE/AVX(单线程),
4、AVX-Db(单线程,双精度),
5、Serial(单线程串行)
对于不同阶数的矩阵乘法运算,运行时间统计如下(单位:秒),Rank表示矩阵阶数:
Rank : | 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 2548 | 3048 | 3548 | 4048 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
C++Amp: | 0.039954 | 0.000432 | 0.000460 | 0.000715 | 0.001594 | 0.005016 | 0.030988 | 0.426671 | 0.934444s | 2.24189 | 3.799203 | 3.069859s |
C++PPL : | 0.000215 | 0.000128 | 0.000076 | 0.000227 | 0.001685 | 0.014039 | 0.271222 | 4.000625 | 8.792314 | 15.768285 | 27.04492 | 42.068705 |
SSE/AVX: | 0.000005 | 0.000019 | 0.000087 | 0.000353 | 0.002055 | 0.01773 | 0.129564 | 2.449093 | 4.760192 | 7.474997 | 11.942498 | 17.434507 |
AVX-Db : | 0.000004 | 0.000022 | 0.000080 | 0.00051 | 0.00419 | 0.032692 | 0.547273 | 4.430325 | 8.523084 | 13.997932 | 22.1742 | 33.316449 |
Serial : | 0.000003 | 0.000025 | 0.000165 | 0.001467 | 0.013698 | 0.114402 | 0.939655 | 29.144466 | 70.799408 | 0 | 0 | 0 |
- C++Amp在数据量小时候(64x64阶以内)没有速度优势,反而很慢,由于GPU数据交换花了大量时间。
- SSE/AVX:宽指令在(128阶以内)速度最快。可以进一步通过多线程结合宽指令提速。
- 串行方式低阶运算尚可,20阶以上开始落后。
- C++Amp在512x512以上表现出更高的效率。
- PPL多线程方式一直不温不火,并未体现出横向对比优势。
- AVX指令运算双精度浮点(AVX-double)在256阶以下速度尚可,阶数提高后效果不好。
- Serial串行运算在大于64阶以后,运行时间成指数级增加,基本没有应用价值。
- 在大于1000阶的高阶计算中,C++Amp(GPU加速)效率最高,其次是SSE/AVX宽指令浮点运算。
- 采用Nvidia的cuda效果应该更好,但本次未作测试对比。
- 综合考虑:“SSE/AVX+多线程”组合的实用性和效率最高,更适合轻量级的高速运用场景。 测试中SSE/AVX仅采用单线程,速度不俗,还可继续扩展为多线程提高速度。关键是SSE/AVX宽指令代码的依赖性极低,不需要额外的使用开销,不需要任何库支持(只需cpu指令集支持即可),能实现轻量级的高速并行计算。
- 而采用C++Amp或cuda,面临低阶运算GPU数据交换开销远大于运算开销情况,得不偿失。他们都需要额外的库支持,且必须借助GPU。其中,cuda更是需要安装庞大的巨量库和驱动,且必须使用Nvidia显卡,移植性便捷性较差。
采用的部分模板类代码: “CLMatrix.h” 头文件.
测试代码:
//....其他头文件
#include <windows.h>
#include <amp.h>
#include <ppl.h>
#include "CLMatrix.h"
using namespace concurrency;
int main() {
CLMatrixD recd;
int cyc = 5;
int rank = 16;
for (; rank < 4100; )
{
if (rank > 1024) cyc =