Skip to content

Instantly share code, notes, and snippets.

@Hafthor
Last active August 21, 2022 00:22
Show Gist options
  • Save Hafthor/545022345ae5740b6fb8667ef7986e0a to your computer and use it in GitHub Desktop.
Save Hafthor/545022345ae5740b6fb8667ef7986e0a to your computer and use it in GitHub Desktop.
Works like Array.Copy or Buffer.BlockCopy but with memcpy forward only operation vs memmove
public static void ForwardCopy(byte[] s, uint si, byte[] d, uint di, uint cx) {
unchecked {
// pre copy to qword align to destination
uint cxpre = (8 - (di & 7)) & 7;
if (cx < cxpre) {
// early out if we cannot even align to the first qword
for (int i = 0; i < cx; i++)
d[di++] = s[si++];
return;
}
for (uint i = 0; i < cxpre; i++) d[di++] = s[si++];
// qword copy
var dl = MemoryMarshal.Cast<byte, ulong>(d.AsSpan((int)(di)));
var sl = MemoryMarshal.Cast<byte, ulong>(s.AsSpan((int)(si)));
uint cxloop = (cx - cxpre) >> 3;
for (int i = 0; i < cxloop; i++)
dl[i] = sl[i];
si += cxloop << 3;
di += cxloop << 3;
// post qword remainder copy
uint cxpost = cx - (cxloop << 3) - cxpre;
for (uint i = 0; i < cxpost; i++)
d[di++] = s[si++];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment