Aqui está um programa Rust simples que itera por um array:
use std::time::Instant;
fn main() {
let mut array = vec![0i32; 64 * 1024 * 1024];
let start = Instant::now();
workload(&mut array);
let dur = start.elapsed().as_millis();
println!("duration: {}ms", dur);
}
fn workload(arr: &mut [i32]) {
for i in 0..arr.len() {
arr[i] *= 3;
}
}
Este tempo medido é de 278 ms quando executado com o --release
sinalizador.
Se eu fizer uma pequena alteração, para inicializar o vetor com 1
s em vez de 0
s, haverá uma aceleração drástica - agora ele relata o tempo medido como 17 ms.
Vejo uma aceleração semelhante na minha máquina.
Não tenho 100% de certeza do motivo dessa aceleração, mas a execução perf
deste programa mostra:
- 131K pequenas falhas de página no caso inicializado com zero
- 65 mil pequenas falhas de página no caso de inicializações em 1.
65K é o número de páginas necessárias para o array de 256 MB na minha máquina com tamanhos de página de 4 KiB.
Posso entender por que há falhas de 65 mil páginas, então, no caso de páginas inicializadas por 1: uma falha por página.
Por que há 2x o número de falhas no caso inicializado com zero? Estou ciente da otimização de página zero, mas isso não deveria ainda incorrer em apenas uma única falha de página menor?
Como uma pergunta secundária, poderia ser esse o motivo da aceleração dramática? Não tenho certeza de como atribuir/medir o tempo gasto no tratamento de falhas de página.