galleria_photo_face_rknn_op.../native/face-knn/docs/README1.md
2026-10-03 12:16:58 +02:00

4.7 KiB

Note tecniche e cronologia del kNN OpenCL

Questo documento raccoglie il percorso sperimentale che ha portato al motore kNN OpenCL. Per installazione, compilazione e uso dei binari consultare README.md.

Obiettivo

Input:

float32[N][128]

Gli embedding sono normalizzati L2, quindi cosine similarity e prodotto scalare coincidono. Output:

indices[query_count][TOPK]
scores[query_count][TOPK]

Baseline

DIM=128
TOPK=32
QUERIES=256
LANES_PER_QUERY=8
CHUNK_SIZE=50000

Risultati sperimentali principali

Numero di lane

LANES=4:   9.60 GOP/s
LANES=8:  10.57 GOP/s
LANES=16:  4.04 GOP/s
LANES=32:  1.49 GOP/s

Otto lane sono risultate la configurazione più equilibrata.

Stage benchmark

DOT:             72.79 M vector/s
DOT+threshold:   83.47 M vector/s
TOPK score:      77.94 M vector/s
TOPK+indici:     76.28 M vector/s
kNN completo:    75.22 M vector/s

Vettorizzazione

scalar: 74.37 M vector/s
float4: 84.14 M vector/s
float8: 83.49 M vector/s

Database e query entrambi float4 hanno raggiunto 84.13 M vector/s.

Accumulatori

F4 singolo accumulatore: 74.53 M vector/s
F4 quattro accumulatori: 83.47 M vector/s
F4 quattro acc + unroll2: 70.53 M vector/s
F8 quattro accumulatori: 82.76 M vector/s

L'unrolling esplicito ha peggiorato il code generation del compilatore Mali.

Pressione sui registri

Una query mantenuta in private float4 query[DIM4] ha ridotto le prestazioni a 17.85 M vector/s. Rimuovendo l'array privato si è risaliti a circa 65 M vector/s.

Strategie TOPK

sorted insertion:        78.37 M vector/s
min-replace:             81.99 M vector/s
threshold + min-replace: 82.02 M vector/s

Dimensione TOPK

TOPK=8:  73.87 M vector/s
TOPK=16: 84.60 M vector/s
TOPK=32: 82.53 M vector/s
TOPK=64: 78.81 M vector/s

Benchmark da 350000 embedding

Database: 350000
Query: 256
Dimensione: 128
TOPK: 32
Chunk: 50000
Confronti: 89600000

Variante min-replace:

KNN kernel: 1244.576 ms
Merge GPU: 8.022 ms
Merge CPU globale: 14.039 ms
Tempo complessivo: 1266.638 ms
Vector rate: 71.992 M vector/s
Dot rate: 18.430 GFLOP/s
Traffico: 36.860 GB/s
Indici non validi: 0

Benchmark parametrico:

CPU: 9663.226 ms
OpenCL: 1373.797 ms
Speedup: 7.034x
Posizioni TOPK identiche: 8192 / 8192
Exact ratio: 100%

Trasformazione in motore dinamico

Il kernel produttivo usa definizioni configurabili:

#ifndef DIM
#define DIM 128
#endif

#ifndef TOPK
#define TOPK 32
#endif

#ifndef QUERY_COUNT
#define QUERY_COUNT 1
#endif

#ifndef LANES_PER_QUERY
#define LANES_PER_QUERY 8
#endif

Il limite fisso q >= 256 è diventato q >= QUERY_COUNT. Le definizioni vengono passate a clBuildProgram insieme a -cl-fast-relaxed-math.

Backend CPU

È stato generalizzato per conteggi e dimensione dinamici, TOPK sicuro, ordinamento deterministico, rifiuto di valori non finiti e layout identico a OpenCL.

Backend OpenCL

Il backend:

  1. enumera piattaforme e GPU;
  2. seleziona preferibilmente Mali-G610;
  3. carica il kernel da file;
  4. compila con parametri runtime;
  5. alloca buffer riutilizzabili;
  6. copia il database a chunk;
  7. esegue il kernel;
  8. legge indici e score;
  9. converte indici locali in globali;
  10. effettua il merge TOPK;
  11. rilascia le risorse tramite RAII.

Diagnostica Mali

Il runtime Mali emette arm_release_ver direttamente su stdout. La CLI devia temporaneamente stdout verso stderr durante OpenCL e lo ripristina prima della scrittura JSON.

Validazione reale

Prototype:

0 IMG_0145.JPG cluster_medoid
1 IMG_0141.JPG cluster_medoid
2 IMG_0193.JPG cluster_medoid
3 IMG_0143.JPG greedy_leave_one_out_gain
4 IMG_0146.JPG greedy_leave_one_out_gain

Risultato:

Query: 21
Prototype: 5
Riconosciuti: 20
Sotto soglia: 1
Copertura: 95.2%
Caso sotto soglia: IMG_0183.JPG
Score: 0.466428
Miglior prototype: IMG_0143.JPG

Python contro C++ CPU:

Query confrontate: 21
Mismatch top-1: 0
Mismatch decisione: 0
Errore massimo: 2.643e-7

C++ CPU contro OpenCL:

Dopo leave-one-out: 100 / 100 posizioni identiche
TOPK grezzo: 105 / 105 posizioni identiche
Errore massimo: 3.58e-7

File di riferimento

modules/knn-opencl/reference/knn_benchmark.cpp
modules/knn-opencl/reference/knn_float4_minreplace_validate_benchmark.cpp
modules/knn-opencl/reference/validation-opencl-350k.txt
modules/knn-opencl/reference/validation-minreplace-350k.txt
modules/knn-opencl/reference/VALIDATION.md
VALIDATION_JESSICA.md

Sviluppi futuri

backend auto
cache del programma OpenCL
indice persistente dei prototype
margine fra prima e seconda identità
modalità shadow applicativa
metriche operative