From df71de64c8e64abb429e62adbd6ac04394387a05 Mon Sep 17 00:00:00 2001 From: CasualPokePlayer <50538166+CasualPokePlayer@users.noreply.github.com> Date: Sun, 2 Apr 2023 03:45:34 -0700 Subject: [PATCH] speedup delta stating with disks with simple track tracking, should be within acceptable performance bounds (more or less) --- src/BizHawk.Common/DeltaSerializer.cs | 4 ++-- src/BizHawk.Common/Serializer.cs | 2 +- .../Computers/Commodore64/Media/Disk.cs | 16 +++++++++++++++- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/src/BizHawk.Common/DeltaSerializer.cs b/src/BizHawk.Common/DeltaSerializer.cs index 0851199f9e..2c4bb11844 100644 --- a/src/BizHawk.Common/DeltaSerializer.cs +++ b/src/BizHawk.Common/DeltaSerializer.cs @@ -9,7 +9,7 @@ namespace BizHawk.Common /// public static class DeltaSerializer { - public static byte[] GetDelta(ReadOnlySpan original, ReadOnlySpan data) + public static ReadOnlySpan GetDelta(ReadOnlySpan original, ReadOnlySpan data) where T : unmanaged { var orignalAsBytes = MemoryMarshal.AsBytes(original); @@ -94,7 +94,7 @@ namespace BizHawk.Common } } - return ret.Slice(0, retSize).ToArray(); + return ret.Slice(0, retSize); } public static void ApplyDelta(ReadOnlySpan original, Span data, ReadOnlySpan delta) diff --git a/src/BizHawk.Common/Serializer.cs b/src/BizHawk.Common/Serializer.cs index 16200db7b3..cced1c3d10 100644 --- a/src/BizHawk.Common/Serializer.cs +++ b/src/BizHawk.Common/Serializer.cs @@ -759,7 +759,7 @@ namespace BizHawk.Common } else { - var delta = DeltaSerializer.GetDelta(original, data); + var delta = DeltaSerializer.GetDelta(original, data).ToArray(); // TODO: don't create array here (need .net update to write span to binary writer) Sync(name, ref delta, useNull: false); } } diff --git a/src/BizHawk.Emulation.Cores/Computers/Commodore64/Media/Disk.cs b/src/BizHawk.Emulation.Cores/Computers/Commodore64/Media/Disk.cs index c67886699a..ff9bfe31ae 100644 --- a/src/BizHawk.Emulation.Cores/Computers/Commodore64/Media/Disk.cs +++ b/src/BizHawk.Emulation.Cores/Computers/Commodore64/Media/Disk.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Diagnostics; using System.Linq; using BizHawk.Common; @@ -12,6 +13,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Media public const int FluxEntriesPerTrack = FluxBitsPerTrack / FluxBitsPerEntry; private readonly int[][] _tracks; private readonly int[][] _originalMedia; + private bool[] _usedTracks; public bool Valid; public bool WriteProtected; @@ -24,6 +26,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Media _tracks = new int[trackCapacity][]; FillMissingTracks(); _originalMedia = _tracks.Select(t => (int[])t.Clone()).ToArray(); + _usedTracks = new bool[trackCapacity]; Valid = true; } @@ -46,6 +49,7 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Media FillMissingTracks(); Valid = true; _originalMedia = _tracks.Select(t => (int[])t.Clone()).ToArray(); + _usedTracks = new bool[trackCapacity]; } private int[] ConvertToFluxTransitions(int density, byte[] bytes, int fluxBitOffset) @@ -133,16 +137,26 @@ namespace BizHawk.Emulation.Cores.Computers.Commodore64.Media public int[] GetDataForTrack(int halftrack) { + _usedTracks[halftrack] = true; // TODO: probably can be smarter about this with the WriteProtected flag return _tracks[halftrack]; } public void SyncState(Serializer ser) { ser.Sync(nameof(WriteProtected), ref WriteProtected); + var oldUsedTracks = _usedTracks; // Sync changes reference if loading state (we don't care in the saving state case) + ser.Sync(nameof(_usedTracks), ref _usedTracks, useNull: false); for (var i = 0; i < _tracks.Length; i++) { - ser.SyncDelta($"MediaState{i}", _originalMedia[i], _tracks[i]); + if (_usedTracks[i]) + { + ser.SyncDelta($"MediaState{i}", _originalMedia[i], _tracks[i]); + } + else if (ser.IsReader && oldUsedTracks[i]) // _tracks[i] might be different, but in the state it wasn't, so just copy _originalMedia[i] + { + _originalMedia[i].AsSpan().CopyTo(_tracks[i]); + } } } }