版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
一直想着用硬件加速处理图像的运算,今天尝试了一下。我选择了amp作为硬件加速测试的应用。然而刚加入 “#include <amp.h>”就提示一堆错误。
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\ratio(111): error C2065: “INTMAX_MAX”: 未声明的标识符
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\ratio(123): note: 参见对正在编译的类 模板 实例化“std::ratio<_Nx,_Dx>”的引用
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\ratio(113): error C2065: “INTMAX_MAX”: 未声明的标识符
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\ratio(26): error C2065: “INTMAX_MAX”: 未声明的标识符
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\ratio(165): note: 参见对正在编译的类 模板 实例化“std::_Ratio_add<_R1,_R2>”的引用
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\ratio(216): error C2338: integer arithmetic overflow
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(966): note: 参见对正在编译的类 模板 实例化“std::_Ratio_multiply_sfinae<std::ratio<100,1>,std::nano,false,void>”的引用
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(966): error C2794: “type”: 不是“std::_Ratio_multiply_sfinae<std::ratio<100,1>,std::nano,false,void>”的任何直接或间接基类的成员
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(966): error C2938: “ratio_multiply<std::ratio<100,1>,std::nano>”: 未能使别名模板专用化
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(966): error C2062: 意外的类型“unknown-type”
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(966): error C2238: 意外的标记位于“;”之前
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(968): error C2065: “period”: 未声明的标识符
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(968): error C2923: “std::chrono::duration”: 对于参数“_Period”,“period”不是有效的 模板 类型变量
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(969): error C3203: “duration”: 未专用化的 类 模板 不能用作 模板 变量,该变量属于 模板 参数“_Duration”,应为 real 类型
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(231): error C2825: '_Duration': 当后面跟“::”时必须为类或命名空间
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(973): note: 参见对正在编译的类 模板 实例化“std::chrono::time_point<std::chrono::system_clock,int>”的引用
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(231): error C2510: “_Duration”:“::”的左边必须是类/结构/联合
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(231): error C3646: “rep”: 未知重写说明符
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(231): error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(232): error C2825: '_Duration': 当后面跟“::”时必须为类或命名空间
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(232): error C2510: “_Duration”:“::”的左边必须是类/结构/联合
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(232): error C3646: “period”: 未知重写说明符
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(232): error C4430: 缺少类型说明符 - 假定为 int。注意: C++ 不支持默认 int
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(235): error C2338: duration must be an instance of std::duration
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(974): error C2440: “<function-style-cast>”: 无法从“__int64”转换为“std::chrono::system_clock::duration”
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(974): note: 无构造函数可以接受源类型,或构造函数重载决策不明确
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(979): error C2228: “.count”的左边必须有类/结构/联合
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(979): note: 类型是“int”
1>C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(985): error C2440: “<function-style-cast>”: 无法从“__int64”转换为“std::chrono::system_clock::duration”
1> C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\include\chrono(985): note: 无构造函数可以接受源类型,或构造函数重载决策不明确
搜索到一个解决方法:添加宏定义__STDC_LIMIT_MACROS
我选择省事的做法,在#include <amp.h>之前加:
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif // !__STDC_LIMIT_MACROS
之后就是并行写法,貌似amp不支持char字符的运算,只好采用整型,将ARGB缓存unsigned int的模式
unsigned int total = width*height;
unsigned int *list = (unsigned int *)addr;
concurrency::array_view<unsigned int, 1> testView(total, list);
concurrency::parallel_for_each(testView.extent, [=](concurrency::index<1> idx) restrict(amp)
{
unsigned int cl = testView[idx];
unsigned int alpha = cl >> 24;
if (alpha)
{
unsigned int red = (cl >> 16) & 0xFF;
unsigned int green = (cl >> 8) & 0xFF;
unsigned int blue = cl & 0xFF;
red = red *alpha / 255;
green = green *alpha / 255;
blue = blue *alpha / 255;
cl = (alpha << 24) + (red << 16) + (green << 8) + blue;
}
testView[idx] = cl;
});
testView.synchronize();
上面随便实现了位图的预乘,貌似可以用了。
下面是附加注释:
concurrency::array_view<数据类型, 数组维度>testView(数据大小, 数据指针);
这里的数据大小和数据指针的类型有关。
concurrency::parallel_for_each(testView.extent, [=](concurrency::index<数组维度> idx) restrict(amp)
其中[=]属于lambda表达式,“The capture clause, [=], specifies that the body of the lambda expression accesses all captured variables by value, which in this case are ...(testView). ”,我暂时也搞不懂这个,先搁置一下。
testView.synchronize();
这句是同步数据的作用,就算不用这句,数据也会同步,可能会有延时吧。
一张1920*1080的图像的速度对比不算很明显
gpu time=13035
cpu time=18048
但是如果是批量处理的话,效率应该高不少。