我编写了一个小测试函数,它的行为与我想要的不同。
基本上,它应该读取一个数组并写回它的内容(稍后,当它工作时,它应该做更多,但现在即使这样也失败了)。
调试到 GPU 代码,我看到前几次迭代(不知何故并行执行.. 这可能对 GPU 有意义,但当我调试时让我感到惊讶)工作正常.. 但是,在 1-2 次调试后继续(F5),一些以前正确设置的值被 0 覆盖。我真的不明白..当我再次上CPU时,许多值都是0,即使它们不应该是0(基本上,它们应该有原始数据,这是一个简单的测试序列)。
#include "stdafx.h"
#include <amp.h>
typedef unsigned char byte;
using namespace concurrency;
void AMPChangeBrightnessContrastWrapper2(byte* a, int len, float brightness, float contrast)
{
array_view<unsigned int> dst(len/4, (unsigned int*)a);
//dst.discard_data();
parallel_for_each(dst.extent, [=](index<1> idx) restrict(amp)
{
// split into bytes (in floats)
float temp1 = (dst[idx]) - (dst[idx] >> 8) * 256;
// this completely fails! float temp1 = dst[idx] & 0xFF;
float temp2 = (dst[idx] >> 8) - (dst[idx] >> 16) * 256;
float temp3 = (dst[idx] >> 16) - (dst[idx] >> 24) * 256;
float temp4 = (dst[idx] >> 24);
// convert back to int-array
dst[idx] = (int)(temp1 + temp2 * 256 + temp3 * 65536 + temp4 * 16777216);
});
//dst.synchronize();
}
int _tmain(int argc, _TCHAR* argv[])
{
const int size = 30000;
byte* a = new byte[size];
// generate some unique test sequence.. first 99 numbers are just 0..98
for (int i = 0; i < size; ++i)
a[i] = (byte)((i + i / 99) % 256);
AMPChangeBrightnessContrastWrapper2(a, size, -10.0f, 1.1f);
for (int i = 0; i < 50; ++i)
printf("%i, ", a[i]);
char out[20];
scanf_s("%s", out);
return 0;
}
如此简单(计划)的步骤:
- 初始化数组
- 将数组传递给 GPU(作为无符号整数数组)
- 将每个 unsigned int 拆分为 4 个字节并将它们存储在浮点数中
- (做一些计算,为简单起见这里省略)
- 将 bytes-stored-in-floats 再次连接到原始位置
- (重复)
如果您想知道..那应该是颜色值..
结果是:
- 一些值符合预期,但大多数值不同
- 似乎特别是字节0(每个无符号整数)会有一个坏值
- 我首先尝试使用 & 0xFF 转换 unsigned int->byte->float 但这似乎完全失败了
输出是(但应该只是从 0 开始递增的数字):
0, 1, 2, 3, 0, 5, 6, 7, 0, 9, 10, 11, 16, 13, 14, 15, 0, 17, 18, 19, 32, 21, 22, 23, 32, 25, 26, 27, 32, 29, 30, 31, 0, 33, 34, 35, 64, 37, 38, 39, 64, 41, 42, 43, 64, 45, 46, 47, 64, 49,
问题:
- 为什么& 0xFF有问题?
- 为什么每个 unsigned int 的字节 0 都分配了一个奇怪的值?
- 我想我不能创建一个字节数组视图,我必须使用整数或浮点数?
- 注释掉 .synchronize 最终并没有改变任何东西 - 怎么会?