[GPU] performance: negative interval filter
This commit is contained in:
parent
4799a1f82f
commit
b4c065a0b0
|
|
@ -363,7 +363,7 @@ public sealed partial class GuestImageCache
|
|||
bool IGuestImageStore.MarkCpuWrite(ulong address, ulong size)
|
||||
{
|
||||
GpuMemoryAccessProfile.CountImageCpuWrite();
|
||||
if (!IsValidRange(address, size))
|
||||
if (!IsValidRange(address, size) || !_pageOwners.MayHaveOwners(address, size))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -107,6 +107,7 @@ public sealed class ImagePageOwnerTable
|
|||
public const ulong AddressSpaceSize = 1UL << AddressSpaceBits;
|
||||
|
||||
private readonly PageOwnerList?[]?[] _firstLevel = new PageOwnerList?[]?[1 << FirstLevelBits];
|
||||
private readonly long[] _everOwnedPages = new long[PageCount / 64];
|
||||
|
||||
public int AllocatedBucketCount { get; private set; }
|
||||
|
||||
|
|
@ -129,7 +130,28 @@ public sealed class ImagePageOwnerTable
|
|||
AllocatedBucketCount++;
|
||||
}
|
||||
|
||||
return bucket[page & (BucketEntries - 1)] ??= new PageOwnerList();
|
||||
var owners = bucket[page & (BucketEntries - 1)] ??= new PageOwnerList();
|
||||
Interlocked.Or(ref _everOwnedPages[page / 64], 1L << (int)(page % 64));
|
||||
return owners;
|
||||
}
|
||||
|
||||
// Bits are never cleared: a false result can safely bypass the image-cache lock.
|
||||
public bool MayHaveOwners(ulong address, ulong size)
|
||||
{
|
||||
if (!TryGetPageRange(address, size, out var first, out var lastExclusive))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var page = first; page < lastExclusive; page++)
|
||||
{
|
||||
if ((Volatile.Read(ref _everOwnedPages[page / 64]) & (1L << (int)(page % 64))) != 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// The half-open page interval of a non-empty byte range inside the address space.
|
||||
|
|
|
|||
|
|
@ -11,6 +11,19 @@ namespace SharpEmu.Libs.Tests.Gpu.Images;
|
|||
[Collection(SchedulingStateCollection.Name)]
|
||||
public sealed class ImagePageOwnerTableTests
|
||||
{
|
||||
[Fact]
|
||||
public void OwnerSummaryRejectsOnlyPagesThatNeverHadAnOwner()
|
||||
{
|
||||
var table = new ImagePageOwnerTable();
|
||||
var page = ImagePageOwnerTable.BucketEntries;
|
||||
var address = (ulong)page << ImagePageOwnerTable.PageBits;
|
||||
Assert.False(table.MayHaveOwners(address, 4));
|
||||
table.GetOrCreate((ulong)page).Add(Owner(1));
|
||||
Assert.True(table.MayHaveOwners(address, 4));
|
||||
Assert.True(table.MayHaveOwners(address - 4, 8));
|
||||
Assert.False(table.MayHaveOwners(address - 4, 4));
|
||||
}
|
||||
|
||||
private static ResourceSlotIdentifier Owner(uint index) => new(index, 1);
|
||||
|
||||
[Fact]
|
||||
|
|
|
|||
Loading…
Reference in New Issue