Как мне объявить галогенид Fun c с float16_t? - PullRequest
0 голосов
/ 13 июля 2020

скажем, я хочу выполнить скользящее среднее горизонтальное по оси x изображения.

Func g;
g(x,y) = (img(x-1,y) + img(x,y) + img(x+1,y))/3.f;
h(x,y) = cast<uint8_t>(g(x,y) + 0.5f);

Использование float32 для g (x, y) кажется излишним, но меня волнует точность, поэтому целочисленное деление не рекомендуется. Могу ли я использовать float16_t вместо float32_t для увеличения пропускной способности?

Можно ли это сделать таким образом?

Expr three = <cast>(float16_t(3.f));
Expr point5 = <cast>float16_t(0.5f);
g(x,y) = (img(x-1,y) + img(x,y) + img(x+1,y))/three;
h(x,y) = cast<uint8_t>(g(x,y) + point5);

Я собираюсь использовать автоматический планировщик для выполнения этой работы. Похоже, у avx2 есть возможность параллельно обрабатывать float16_t. Возникнет ли проблема, если этот фрагмент кода будет сгенерирован с целью x86_64-sse4.1?

1 Ответ

2 голосов
/ 14 июля 2020

преобразование float16 существует на avx2, но на самом деле он не выполняет математические вычисления float16 параллельно, поэтому он будет медленным. Вместо этого я рекомендую использовать uint16 для такого рода вещей. На самом деле это более точно, чем использование чисел с плавающей запятой для кода, который вы указали:

Func in16, g;
in16(x, y) = cast<uint16_t>(img(x, y));
g(x,y) = in16(x-1,y) + in16(x,y) + in16(x+1,y);
h(x,y) = cast<uint8_t>(g(x,y) + 1)/3);

Операция деления будет использовать векторную инструкцию x86 pmulhuw, поэтому она будет быстрой.

...