mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-bigint: Apply 4x loop unrolling to uadd for performance
Improved the `uadd` function by applying 4x loop unrolling to its core addition loops. This optimization aims to reduce loop overhead and improve instruction-level parallelism, leading to better performance for multi-limb addition operations. Co-authored-by: Gemini <gemini@google.com>
This commit is contained in:
@@ -347,13 +347,53 @@ uadd(mpz_t *z, mpz_t *x, mpz_t *y)
|
||||
size_t i;
|
||||
|
||||
/* Add overlapping limbs from both operands */
|
||||
for (i = 0; i < x->sz; i++) {
|
||||
/* 4x unrolled loop for better performance */
|
||||
for (i = 0; i + 4 <= x->sz; i += 4) {
|
||||
c += (mp_dbl_limb)y->p[i] + (mp_dbl_limb)x->p[i];
|
||||
z->p[i] = LOW(c);
|
||||
c >>= DIG_SIZE;
|
||||
|
||||
c += (mp_dbl_limb)y->p[i+1] + (mp_dbl_limb)x->p[i+1];
|
||||
z->p[i+1] = LOW(c);
|
||||
c >>= DIG_SIZE;
|
||||
|
||||
c += (mp_dbl_limb)y->p[i+2] + (mp_dbl_limb)x->p[i+2];
|
||||
z->p[i+2] = LOW(c);
|
||||
c >>= DIG_SIZE;
|
||||
|
||||
c += (mp_dbl_limb)y->p[i+3] + (mp_dbl_limb)x->p[i+3];
|
||||
z->p[i+3] = LOW(c);
|
||||
c >>= DIG_SIZE;
|
||||
}
|
||||
|
||||
/* Handle remaining elements */
|
||||
for (; i < x->sz; i++) {
|
||||
c += (mp_dbl_limb)y->p[i] + (mp_dbl_limb)x->p[i];
|
||||
z->p[i] = LOW(c);
|
||||
c >>= DIG_SIZE;
|
||||
}
|
||||
|
||||
/* Add remaining limbs from larger operand */
|
||||
/* 4x unrolled loop for better performance */
|
||||
for (; i + 4 <= y->sz; i += 4) {
|
||||
c += y->p[i];
|
||||
z->p[i] = LOW(c);
|
||||
c >>= DIG_SIZE;
|
||||
|
||||
c += y->p[i+1];
|
||||
z->p[i+1] = LOW(c);
|
||||
c >>= DIG_SIZE;
|
||||
|
||||
c += y->p[i+2];
|
||||
z->p[i+2] = LOW(c);
|
||||
c >>= DIG_SIZE;
|
||||
|
||||
c += y->p[i+3];
|
||||
z->p[i+3] = LOW(c);
|
||||
c >>= DIG_SIZE;
|
||||
}
|
||||
|
||||
/* Handle remaining elements */
|
||||
for (; i < y->sz; i++) {
|
||||
c += y->p[i];
|
||||
z->p[i] = LOW(c);
|
||||
|
||||
Reference in New Issue
Block a user