Вы действительно должны получить тестовое устройство с SoC в порядке.Чипы Apple серии A вышли из строя, безусловно, самые мощные, если быть точными.
Ваша реализация может работать на вашем iPhone достаточно быстро, но будет чуть быстрее, чем самые простые версии C наядра по порядку, непригодные для использования.
Подумайте дважды, прежде чем приступить к написанию циклов на NEON.Вы можете избежать так называемых «горизонтальных» операций в большинстве случаев, транспонируя матрицу, а затем выполнить «вертикальную» математику.
#define vuzp8(a, b, c) ({ \
c = vuzp_u8(a, b); \
a = c.val[0]; \
b = c.val[1]; \
})
void foo(uint8_t *pDst, uint8_t *pSrc)
{
uint8x8x4_t top, bottom;
uint8x8x2_t temp;
top = vld4_u8(pSrc);
pSrc += 32;
bottom = vld4_u8(pSrc);
vuzp8(top.val[0], bottom.val[0], temp);
vuzp8(top.val[1], bottom.val[1], temp);
vuzp8(top.val[2], bottom.val[2], temp);
vuzp8(top.val[3], bottom.val[3], temp);
top.val[0] += bottom.val[0];
top.val[1] += bottom.val[1];
top.val[2] += bottom.val[2];
top.val[3] += bottom.val[3];
top.val[0] += top.val[1];
top.val[2] += top.val[3];
top.val[0] += top.val[2];
top.val[0] = vclz_u8(top.val[0]);
vst1_u8(pDst, top.val[0]);
}
Другой пример, когда вы спрашиваетесебя, если intrinsux
имеет смысл вообще.Его неуклюжесть делает код намного более сложным, и он недостаточно выразителен, чтобы сделать три 128-битных плюс одно 64-битное добавление вместо шести 64-битных.
Кроме того, вы должны дважды проверить, не компилятор не сделалопять все испортить, особенно когда вы делаете перестановки (vzip, vuzp, vtrn
)
Я думаю, что машинный код будет в порядке на aarch32
, но я не уверен в aarch64
, где инструкции по перестановкеочень разные.
Я думаю, что вы уже поняли, почему я ненавижу intrinsux
как вредитель.Это больше неприятностей, чем любая помощь.
PS: Планшет Android Teclast P10 является хорошим кандидатом в качестве тестового устройства aarch64
: все восемь ядер одинаковы, Android 7.12 64bitустановлен, и стоит всего около $ 100.