Я написал небольшую тестовую функцию, которая ведет себя не так, как я хочу.
По сути, он должен читать массив и записывать обратно его содержимое (позже, когда это сработает, он должен будет делать больше, но сейчас даже это не удается).
Выполняя отладку кода графического процессора, я увидел, что первые несколько итераций (каким-то образом выполняющиеся параллельно... что, вероятно, имеет смысл для графического процессора, но меня удивляет, когда я отлаживаю) работают нормально... но затем, после 1-2 команд Debug-Continues (F5), некоторые ранее правильно установленные значения заменяются нулями. Я действительно не понимаю ... к тому времени, когда я снова нахожусь на ЦП, многие значения равны 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 (как массив целых чисел без знака)
- разделить каждое целое число без знака на 4 байта и сохранить их в числах с плавающей запятой
- (проведите некоторые расчеты, здесь опущенные для простоты)
- снова объединить байты, хранящиеся в числах с плавающей запятой, в исходное положение
- (повторить)
Если вам интересно... это должны быть значения цвета...
Результат:
- некоторые значения соответствуют ожидаемым, но большинство из них имеют разные значения
- кажется, что особенно байт 0 (каждого целого числа без знака) будет иметь плохое значение
- Сначала я попытался преобразовать unsigned int->byte->float с помощью & 0xFF, но, похоже, это полностью не удалось.
Выход (но должен быть просто увеличивающимся числом, начиная с 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?
- почему байту 0 каждого беззнакового целого числа присваивается странное значение?
- Я полагаю, я не могу создать массив байтов, мне нужно использовать целые числа или числа с плавающей запятой?
- комментирование .synchronize в конце концов ничего не изменило - как так?