Optimized transpose (#191)

* Start work on optimized transpose

* Optimized transpose: 12-14% improvement on benchmark

* Transpose: Avoid bounds checks and change order of loops dynamically

* Transpose: re-enable bounds checks
This commit is contained in:
Jakub Nabaglo 2021-08-18 16:45:17 -07:00 committed by GitHub
parent d41924dad3
commit 7c97751c13
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -38,12 +38,32 @@ pub(crate) fn transpose_poly_values<F: Field>(polys: Vec<PolynomialValues<F>>) -
pub fn transpose<F: Field>(matrix: &[Vec<F>]) -> Vec<Vec<F>> { pub fn transpose<F: Field>(matrix: &[Vec<F>]) -> Vec<Vec<F>> {
let l = matrix.len(); let l = matrix.len();
let w = matrix[0].len(); let w = matrix[0].len();
let mut transposed = vec![vec![F::ZERO; l]; w];
let mut transposed = vec![vec![]; w];
for i in 0..w { for i in 0..w {
for j in 0..l { transposed[i].reserve_exact(l);
transposed[i][j] = matrix[j][i]; unsafe {
// After .reserve_exact(l), transposed[i] will have capacity at least l. Hence, set_len
// will not cause the buffer to overrun.
transposed[i].set_len(l);
} }
} }
// Optimization: ensure the larger loop is outside.
if w >= l {
for i in 0..w {
for j in 0..l {
transposed[i][j] = matrix[j][i];
}
}
} else {
for j in 0..l {
for i in 0..w {
transposed[i][j] = matrix[j][i];
}
}
}
transposed transposed
} }