Skip to content

Commit df71de6

Browse files
speedup delta stating with disks with simple track tracking, should be within acceptable performance bounds (more or less)
1 parent 3ffb6c3 commit df71de6

File tree

3 files changed

+18
-4
lines changed

3 files changed

+18
-4
lines changed

src/BizHawk.Common/DeltaSerializer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace BizHawk.Common
99
/// </summary>
1010
public static class DeltaSerializer
1111
{
12-
public static byte[] GetDelta<T>(ReadOnlySpan<T> original, ReadOnlySpan<T> data)
12+
public static ReadOnlySpan<byte> GetDelta<T>(ReadOnlySpan<T> original, ReadOnlySpan<T> data)
1313
where T : unmanaged
1414
{
1515
var orignalAsBytes = MemoryMarshal.AsBytes(original);
@@ -94,7 +94,7 @@ public static byte[] GetDelta<T>(ReadOnlySpan<T> original, ReadOnlySpan<T> data)
9494
}
9595
}
9696

97-
return ret.Slice(0, retSize).ToArray();
97+
return ret.Slice(0, retSize);
9898
}
9999

100100
public static void ApplyDelta<T>(ReadOnlySpan<T> original, Span<T> data, ReadOnlySpan<byte> delta)

src/BizHawk.Common/Serializer.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -759,7 +759,7 @@ public void SyncDelta<T>(string name, T[] original, T[] data)
759759
}
760760
else
761761
{
762-
var delta = DeltaSerializer.GetDelta<T>(original, data);
762+
var delta = DeltaSerializer.GetDelta<T>(original, data).ToArray(); // TODO: don't create array here (need .net update to write span to binary writer)
763763
Sync(name, ref delta, useNull: false);
764764
}
765765
}

src/BizHawk.Emulation.Cores/Computers/Commodore64/Media/Disk.cs

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
using System;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
34
using System.Linq;
45
using BizHawk.Common;
56

@@ -12,6 +13,7 @@ public sealed class Disk
1213
public const int FluxEntriesPerTrack = FluxBitsPerTrack / FluxBitsPerEntry;
1314
private readonly int[][] _tracks;
1415
private readonly int[][] _originalMedia;
16+
private bool[] _usedTracks;
1517
public bool Valid;
1618
public bool WriteProtected;
1719

@@ -24,6 +26,7 @@ public Disk(int trackCapacity)
2426
_tracks = new int[trackCapacity][];
2527
FillMissingTracks();
2628
_originalMedia = _tracks.Select(t => (int[])t.Clone()).ToArray();
29+
_usedTracks = new bool[trackCapacity];
2730
Valid = true;
2831
}
2932

@@ -46,6 +49,7 @@ public Disk(IList<byte[]> trackData, IList<int> trackNumbers, IList<int> trackDe
4649
FillMissingTracks();
4750
Valid = true;
4851
_originalMedia = _tracks.Select(t => (int[])t.Clone()).ToArray();
52+
_usedTracks = new bool[trackCapacity];
4953
}
5054

5155
private int[] ConvertToFluxTransitions(int density, byte[] bytes, int fluxBitOffset)
@@ -133,16 +137,26 @@ private void FillMissingTracks()
133137

134138
public int[] GetDataForTrack(int halftrack)
135139
{
140+
_usedTracks[halftrack] = true; // TODO: probably can be smarter about this with the WriteProtected flag
136141
return _tracks[halftrack];
137142
}
138143

139144
public void SyncState(Serializer ser)
140145
{
141146
ser.Sync(nameof(WriteProtected), ref WriteProtected);
147+
var oldUsedTracks = _usedTracks; // Sync changes reference if loading state (we don't care in the saving state case)
148+
ser.Sync(nameof(_usedTracks), ref _usedTracks, useNull: false);
142149

143150
for (var i = 0; i < _tracks.Length; i++)
144151
{
145-
ser.SyncDelta($"MediaState{i}", _originalMedia[i], _tracks[i]);
152+
if (_usedTracks[i])
153+
{
154+
ser.SyncDelta($"MediaState{i}", _originalMedia[i], _tracks[i]);
155+
}
156+
else if (ser.IsReader && oldUsedTracks[i]) // _tracks[i] might be different, but in the state it wasn't, so just copy _originalMedia[i]
157+
{
158+
_originalMedia[i].AsSpan().CopyTo(_tracks[i]);
159+
}
146160
}
147161
}
148162
}

0 commit comments

Comments
 (0)