Disk: ReadDriver: Add unified cache

Previously, we had to copy an entire block out of the
old cache every time we wanted to read even a single
byte from it.

This ended up being a fairly significant performance
issue, in addition to the fact that the caching code
was duplicated.
This commit is contained in:
Paul Hollinsky
2022-04-14 18:26:44 -04:00
parent d45d708446
commit 103f938d69
10 changed files with 316 additions and 245 deletions
+21 -32
View File
@@ -15,38 +15,31 @@ optional<uint64_t> NeoMemoryDiskDriver::readLogicalDiskAligned(Communication& co
if(amount != SectorSize)
return nullopt;
if(cachePos != pos || std::chrono::steady_clock::now() > cachedAt + CacheTime) {
// The cache does not have this data, go get it
const uint64_t currentSector = pos / SectorSize;
auto msg = com.waitForMessageSync([&currentSector, &com] {
return com.sendCommand(Command::NeoReadMemory, {
MemoryTypeSD,
uint8_t(currentSector & 0xFF),
uint8_t((currentSector >> 8) & 0xFF),
uint8_t((currentSector >> 16) & 0xFF),
uint8_t((currentSector >> 24) & 0xFF),
uint8_t(SectorSize & 0xFF),
uint8_t((SectorSize >> 8) & 0xFF),
uint8_t((SectorSize >> 16) & 0xFF),
uint8_t((SectorSize >> 24) & 0xFF)
});
}, NeoMemorySDRead, timeout);
const uint64_t currentSector = pos / SectorSize;
auto msg = com.waitForMessageSync([&currentSector, &com] {
return com.sendCommand(Command::NeoReadMemory, {
MemoryTypeSD,
uint8_t(currentSector & 0xFF),
uint8_t((currentSector >> 8) & 0xFF),
uint8_t((currentSector >> 16) & 0xFF),
uint8_t((currentSector >> 24) & 0xFF),
uint8_t(SectorSize & 0xFF),
uint8_t((SectorSize >> 8) & 0xFF),
uint8_t((SectorSize >> 16) & 0xFF),
uint8_t((SectorSize >> 24) & 0xFF)
});
}, NeoMemorySDRead, timeout);
if(!msg)
return 0;
if(!msg)
return 0;
const auto sdmsg = std::dynamic_pointer_cast<NeoReadMemorySDMessage>(msg);
if(!sdmsg || sdmsg->data.size() != SectorSize) {
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
return nullopt;
}
memcpy(cache.data(), sdmsg->data.data(), SectorSize);
cachedAt = std::chrono::steady_clock::now();
cachePos = pos;
const auto sdmsg = std::dynamic_pointer_cast<NeoReadMemorySDMessage>(msg);
if(!sdmsg || sdmsg->data.size() != SectorSize) {
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
return nullopt;
}
memcpy(into, cache.data(), SectorSize);
memcpy(into, sdmsg->data.data(), SectorSize);
return SectorSize;
}
@@ -61,10 +54,6 @@ optional<uint64_t> NeoMemoryDiskDriver::writeLogicalDiskAligned(Communication& c
if(amount != SectorSize)
return nullopt;
// Clear the cache if we're writing to the cached sector
if(pos == cachePos)
cachedAt = std::chrono::time_point<std::chrono::steady_clock>();
// Requesting an atomic operation, but neoMemory does not support it
// Continue on anyway but warn the caller
if(atomicBuf != nullptr)