Why Nostr? What is Njump?
2025-04-28 11:45:26

ok3e on Nostr: Uma tentativa de incluir otimização assembly arm64 para esta biblioteca Go A fim de ...

Uma tentativa de incluir otimização assembly arm64 para esta biblioteca Go https://github.com/mmcloughlin/geohash
A fim de futuramente criar uma aplicação voltada a eventos e localização.

Tentei fazer o uso do NEON, para que fosse mais performático, utilizei IA para ajudar no desenvolvimento mas ainda não tive a oportunidade de testar.

Se não me engano será compatível com qualquer armv8 em diante. Isso inclui raspberry pi 3 e acima.
// +build arm64

#include "textflag.h"

// func EncodeInt(lat, lng float64) uint64
TEXT ·EncodeInt(SB), NOSPLIT, $0-24
// Verifica se devemos usar o assembly
LDRB R0, ·useAsm(SB)
CMP R0, #1
BNE fallback

// Definições
#define V_LATLNG V0 // vetor com lat, lng
#define V_SCALE V1 // vetor com fatores de escala
#define V_ADD V2 // vetor com fatores de adição
#define V_TMP V3
#define V_INT V4

// Carrega lat e lng para V0 (D0 e D1)
LDR D0, lat+0(FP)
LDR D1, lng+8(FP)

// Prepara os vetores escala e soma
MOVI V1.2D, #0
FMOV D2, #0.005555555555555556
INS V1.D[0], D2
FMOV D2, #0.002777777777777778
INS V1.D[1], D2

MOVI V2.2D, #0
FMOV D3, #1.5
INS V2.D[0], D3
INS V2.D[1], D3

// Multiplica lat/lng por fator de escala
FMUL V0.2D, V0.2D, V1.2D

// Soma fator de adição
FADD V0.2D, V0.2D, V2.2D

// Converte para inteiros
FCVTZS V4.2D, V0.2D

// Agora R1 = LATI, R2 = LNGI
MOV R1, V4.D[0]
MOV R2, V4.D[1]

// Shift right 20 bits
LSR R1, R1, #20
LSR R2, R2, #20

// Agora vamos entrelaçar os bits de forma manual
// (Interleaving bits entre LATI e LNGI)

MOV R3, R1
MOV R4, R2

// Entrelaçamento manual
MOV R5, $0
MOV R6, $0
MOV R7, $0
MOV R8, $0

// Loop de intercalamento dos bits (não muito bonito mas eficiente)
MOV R9, $0
interleave_loop:
CMP R9, #32
BGE interleave_done

// Pega 1 bit de LATI
ANDS R10, R3, $1
LSL R10, R10, R9
ORR R5, R5, R10

// Pega 1 bit de LNGI
ANDS R10, R4, $1
LSL R10, R10, R9
LSL R10, R10, #1
ORR R6, R6, R10

// Avança bits
LSR R3, R3, #1
LSR R4, R4, #1
ADD R9, R9, #2
B interleave_loop

interleave_done:
// Resultado
EOR R0, R5, R6

// Salva
STR R0, ret+16(FP)
RET

fallback:
B ·encodeInt(SB)

#Go #Geohash #ASM
Author Public Key
npub1jxl2tnvnv9gycsy64aze295c3a529lx5sfmzlktf5lxuw805g5wqew0z0n