2013-04-27 4 views
1

У меня 128 32-разрядных значений (пронумерованных от 0 до 127) и иметь их упорядочены следующим образом:Reorder значения при хранении от NEON регистров

0, 32, 64, 96, 1, 33, 65 , 97, ... 31, 63, 95, 127

С этим заказом я загружаю их группами из 4 в регистры NEON для выполнения некоторых вычислений (что требует такого упорядочения). Таким образом, у меня есть q0 = (0, 32, 64, 96) ... и так далее.

мне было интересно, если есть какой-то простой способ хранения их в памяти в их естественном порядке (0 1 2 3 ...)

Другими словами, существует ли какой-нибудь простой способ или трюк, чтобы сделать это :

vst1.u32 {d0[0]}, [r0] 
vst1.u32 {d0[1]}, [r0,#128] 
vst1.u32 {d1[0]}, [r0,#256] 
vst1.u32 {d1[1]}, [r0,#384] 
vst1.u32 {d2[0]}, [r0,#4] 
vst1.u32 {d2[1]}, [r0,#132] 
... 

Я не совсем понимаю, использование @alignment суффикса с vstx и vldx инструкции. Разве это не тот случай, когда это может быть полезно?

+0

Извините, если мой вопрос глуп, но ваш заказ начинается с 1, 32, 64, 96; (+ 31, + 32, + 32), не должен заканчиваться 31,62,94,126, 32,63,95,127, 33,64,96,128? –

+0

Спасибо! Конечно, это была опечатка. – NumberFour

ответ

2

Выравнивание (@ 128, @ 256) используется для подсказки процессору, что чтение/запись не пересекает линию кэша. В этих случаях количество выполненных микроопераций (и, в конечном счете, используемых циклов) может быть уменьшено.

Вместо этого ваше приложение будет использовать формат инструкций, который позволяет хранить/загружать столбцы. Рукоятка ручного вызова этих дорожек, как в подразделе (Store a single lane of N-element structure to memory).

Формат поддерживает оба последовательных регистра: {d0, d1, d2, ...} и пропускает один регистр {d0, d2, d4, ...}.

mov #128, r1 // initialize value for increment 
vst4.32 { d0[0], d2[0], d4[0], d6[0] }, [r0], r1 // columns 0..1 
vst4.32 { d0[1], d2[1], d4[1], d6[1] }, [r0], r1 // store at offset 128 
vst4.32 { d1[0], d3[0], d5[0], d7[0] }, [r0], r1 // columns 2..3 
vst4.32 { d1[1], d3[1], d5[1], d7[1] }, [r0], r1 // columns 2..3 
... etc ... 

Это, пожалуй, лучшее, что можно сделать, так как не хватает регистров перетасовать все на месте. Я считаю, что потребуется 32 Q-регистра.

+0

Это приятно. Но не могли бы вы объяснить, что такое dx [2] и dx [3]? Я думал, что dx имеет ширину 64 бит, поэтому он имеет только dx [0] и dx [1] (нижние 32-разрядные и более высокие 32-разрядные половинки соответственно) – NumberFour

+0

Вы также забыли декремент r0, так как суффиксные приращения постоянные. Во всяком случае, я изменил свой код, и он работает очень хорошо, поэтому я принимаю ваш ответ. Благодаря! – NumberFour

+0

Правильно, нет 32-разрядных индексов d_even [2..3]. Фактически это будет d_odd [0..1]. Во всяком случае, я просто хотел представить какой-то концептуальный код. –