Sto provando a scrivere codice di aggiunta vettoriale ragionevolmente veloce componente-saggio. Sto lavorando con (firmato, credo) interi a 64 bit.Vectorizing Modular Arithmetic
La funzione è
void addRq (int64_t* a, const int64_t* b, const int32_t dim, const int64_t q) {
for(int i = 0; i < dim; i++) {
a[i] = (a[i]+b[i])%q; // LINE1
}
}
Sto compilando con icc -std=gnu99 -O3
(ICC in modo da poter usare SVML in seguito) su un Ivybridge (SSE4.2 e AVX, ma non AVX2).
La mia linea di base sta rimuovendo %q
da LINE1. 100 chiamate di funzione (iterata) con dim=11221184
richiedono 1,6 secondi. ICC auto-vettorizza il codice per SSE; grande.
Voglio davvero fare aggiunte modulari però. Con %q
, ICC non auto-vettorializza il codice e viene eseguito in 11,8 secondi (!). Anche ignorando l'auto-vettorizzazione per il precedente tentativo, questo sembra ancora eccessivo.
Poiché non ho AVX2, la vettorizzazione con SSE richiede SVML, che è forse il motivo per cui ICC non ha auto-vettorializzato. In ogni caso, ecco il mio tentativo di vettorizzare il ciclo interno:
__m128i qs = _mm_set1_epi64x(q);
for(int i = 0; i < dim; i+=2) {
__m128i xs = _mm_load_si128((const __m128i*)(a+i));
__m128i ys = _mm_load_si128((const __m128i*)(b+i));
__m128i zs = _mm_add_epi64(xs,ys);
zs = _mm_rem_epi64(zs,qs);
_mm_store_si128((__m128i*)(a+i),zs);
}
Assemblea per il ciclo principale è:
..B3.4: # Preds ..B3.2 ..B3.12
movdqa (%r12,%r15,8), %xmm0 #59.22
movdqa %xmm8, %xmm1 #60.14
paddq (%r14,%r15,8), %xmm0 #59.22
call __svml_i64rem2 #61.9
movdqa %xmm0, (%r12,%r15,8) #61.36
addq $2, %r15 #56.30
cmpq %r13, %r15 #56.24
jl ..B3.4 # Prob 82% #56.24
Così il codice è sempre Vettorializzare come previsto. So che potrei non ottenere un aumento di velocità 2x grazie a SVML, ma il codice funziona in 12,5 secondi, più lentamente che senza vettorizzazione! È davvero il meglio che si può fare qui?
La chiamata di funzione per il modulo sta uccidendo le prestazioni: si dispone di una conoscenza * a priori * dei possibili valori di 'q'? –
Se si sa che gli input sono completamente ridotti, è meglio usare un confronto e una sottrazione condizionale. – Mysticial
@PaulR q dovrebbe rimanere (fondamentalmente) costante al runtime, ma non sarebbe noto al momento della compilazione. Come potrebbe essere vantaggioso? – crockeea