Extrait de code Rust

Références

Byte swap un Vec<u8>

Deux façon « claires » :

pub fn swap16(src: &mut Vec<u8>) {
    for chunk in src.chunks_exact_mut(2) {
        chunk.swap(0, 1);
    }
}
pub fn swap16(src: &mut Vec<u8>) {
    src.chunks_exact_mut(2).for_each(|chunk| {
        let (s1, s2) = chunk.split_at_mut(1);
        std::mem::swap(&mut s1[0], &mut s2[0]);
    });
}

La méthode qui semble générer le code assembleur le plus efficace est :

pub fn sawp16(my_vec: &mut Vec<u8>) {
    let (head, body, tail) = unsafe { my_vec.align_to_mut::<u16>() };

    for v in body {
        *v = v.swap_bytes();
    }
}

Notez l’utilisation de l’instruction rol :

.LBB18_2:
        rol     word ptr [rcx + rdx], 8
        add     rdx, 2
        cmp     rax, rdx
        jne     .LBB18_2

Changer u16 par u32 permet d’utiliser l’instruction bswap :

.LBB6_1:
        cmp     rcx, rdx
        je      .LBB6_2
        mov     esi, dword ptr [rax + rdx]
        bswap   esi
        mov     dword ptr [rax + rdx], esi
        add     rdx, 4
        jmp     .LBB6_1
.LBB6_2:
        add     rsp, 48
        pop     rbx
        ret