Pergunta

Não estou em posição de entender a diferença entre vld4_f32 e vld4q_f32 nas instruções do néon do braço.

A confusão começou quando eu levantei meus níveis de codificação e comecei a olhar para as instruções da montagem, em vez das intrínsecas menos informativas.

A razão pela qual preciso usar VLD4 Instrução variante aqui é porque, eu gostaria de capturar 4 float32_té de cada 4ª posição da minha grande variedade.

alt text

o vld4_f32 Intrinsics e as instruções de montagem correspondentes se parecem com esta (A partir deste link)

float32x2x4_t vld4_f32 (const float32_t *) 
Form of expected instruction(s): vld4.32 {d0, d1, d2, d3}, [r0]

o vld4q_f32 Intrinsics e suas instruções de montagem correspondentes se parecem com isso

float32x4x4_t vld4q_f32 (const float32_t *) 
Form of expected instruction(s): vld4.32 {d0, d1, d2, d3}, [r0]

Bem, no nível intrínsético A diferença que vejo é do tipo de retorno, mas se eu olhar para a instrução de montagem e o número de registros, ambos se parecem com a mesma. Como o compilador ou o assembler saberão a diferença entre os dois?

Alguém pode esclarecer mais sobre isso e também explicar como posso alcançar o carregamento 4 float32_t valores que estão posicionados a cada 4º local de memória em um único registro?

Foi útil?

Solução

Sim, eu descobri a diferença. Usei o CodESourcery para ver o conteúdo do registro real para todas as instruções de carga. O link que publiquei não fornece os detalhes completos no VLD4Q_F32.

Ok, primeiro vem o vld4_f32, isso carrega 4 d registros (por exemplo, d16-19) cada d O registro tem 64 bits de comprimento, portanto, esta instrução carrega os 8 primeiros valores intercalados com um intervalo de 4, como mostrado na figura abaixo.alt text

No segundo caso, o vld4q_f32, isso carrega 8 d registros (por exemplo, D16-23) em vez de quatro. Para um leitor disso link, não está claro que 8 registros serão carregados. Quando olhei para o código desmontado para um vld4qf32, estava fazendo uso de registros de 8 dias.

Esta instrução realmente fará o que eu esperava para fazer, ou seja, carregar 4 float32_t valores que estão no intervalo de 4, como mostrado na figura abaixo.alt text

Outras dicas

Desmontei dois intrínsecos, talvez ajude a alguém:

// C++
uint32x4x4_t r = vld4q_u32( ( uint32_t *) output );
// assembly
VLD4.32         {D16,D18,D20,D22}, [R0]!
VLD4.32         {D17,D19,D21,D23}, [R0]

// C++
uint32x2x4_t r = vld4_u32( ( uint32_t *) output );
// assembly
VLD4.32         {D20-D23}, [R0]
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top