mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-07 08:07:40 +03:00
Optimize buffer operations for better upload performance
- Replace byte-by-byte copies with memcpy (10-100x faster) - Increase SD write chunk size from 4KB to 16KB - Use static buffer for SD writes to reduce stack usage - Remove unnecessary yield() from handleClient loop The byte-by-byte circular buffer operations were a major bottleneck. Using memcpy with proper wrap-around handling significantly improves throughput.
This commit is contained in:
parent
cc666e5c18
commit
953df1f3f9
@ -327,7 +327,6 @@ void CrossPointWebServerActivity::loop() {
|
|||||||
// in chunks and each handleClient() call processes incoming data
|
// in chunks and each handleClient() call processes incoming data
|
||||||
for (int i = 0; i < HANDLE_CLIENT_ITERATIONS && webServer->isRunning(); i++) {
|
for (int i = 0; i < HANDLE_CLIENT_ITERATIONS && webServer->isRunning(); i++) {
|
||||||
webServer->handleClient();
|
webServer->handleClient();
|
||||||
yield(); // Allow other tasks to run between iterations
|
|
||||||
}
|
}
|
||||||
lastHandleClientTime = millis();
|
lastHandleClientTime = millis();
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,9 +81,17 @@ bool CrossPointWebServer::writeToBuffer(const uint8_t* data, size_t len) const {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < len; i++) {
|
// Use memcpy for efficiency - handle wrap-around case
|
||||||
uploadBuffer[uploadBufferHead] = data[i];
|
const size_t spaceToEnd = UPLOAD_BUFFER_SIZE - uploadBufferHead;
|
||||||
uploadBufferHead = (uploadBufferHead + 1) % UPLOAD_BUFFER_SIZE;
|
if (len <= spaceToEnd) {
|
||||||
|
// Single copy - no wrap
|
||||||
|
memcpy(uploadBuffer + uploadBufferHead, data, len);
|
||||||
|
uploadBufferHead = (uploadBufferHead + len) % UPLOAD_BUFFER_SIZE;
|
||||||
|
} else {
|
||||||
|
// Two copies - wrap around
|
||||||
|
memcpy(uploadBuffer + uploadBufferHead, data, spaceToEnd);
|
||||||
|
memcpy(uploadBuffer, data + spaceToEnd, len - spaceToEnd);
|
||||||
|
uploadBufferHead = len - spaceToEnd;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -97,17 +105,24 @@ size_t CrossPointWebServer::flushBufferToSD(size_t maxBytes) const {
|
|||||||
size_t toWrite = maxBytes > 0 ? std::min(available, maxBytes) : available;
|
size_t toWrite = maxBytes > 0 ? std::min(available, maxBytes) : available;
|
||||||
size_t totalWritten = 0;
|
size_t totalWritten = 0;
|
||||||
|
|
||||||
// Write in chunks to avoid blocking too long
|
// Write larger chunks for better SD performance (16KB)
|
||||||
constexpr size_t CHUNK_SIZE = 4096;
|
constexpr size_t CHUNK_SIZE = 16384;
|
||||||
uint8_t chunk[CHUNK_SIZE];
|
static uint8_t chunk[CHUNK_SIZE]; // Static to avoid stack allocation
|
||||||
|
|
||||||
while (toWrite > 0) {
|
while (toWrite > 0) {
|
||||||
const size_t chunkLen = std::min(toWrite, CHUNK_SIZE);
|
const size_t chunkLen = std::min(toWrite, CHUNK_SIZE);
|
||||||
|
|
||||||
// Copy from circular buffer to linear chunk
|
// Use memcpy - handle wrap-around case
|
||||||
for (size_t i = 0; i < chunkLen; i++) {
|
const size_t dataToEnd = UPLOAD_BUFFER_SIZE - uploadBufferTail;
|
||||||
chunk[i] = uploadBuffer[uploadBufferTail];
|
if (chunkLen <= dataToEnd) {
|
||||||
uploadBufferTail = (uploadBufferTail + 1) % UPLOAD_BUFFER_SIZE;
|
// Single copy - no wrap
|
||||||
|
memcpy(chunk, uploadBuffer + uploadBufferTail, chunkLen);
|
||||||
|
uploadBufferTail = (uploadBufferTail + chunkLen) % UPLOAD_BUFFER_SIZE;
|
||||||
|
} else {
|
||||||
|
// Two copies - wrap around
|
||||||
|
memcpy(chunk, uploadBuffer + uploadBufferTail, dataToEnd);
|
||||||
|
memcpy(chunk + dataToEnd, uploadBuffer, chunkLen - dataToEnd);
|
||||||
|
uploadBufferTail = chunkLen - dataToEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
const size_t written = uploadFile.write(chunk, chunkLen);
|
const size_t written = uploadFile.write(chunk, chunkLen);
|
||||||
@ -119,7 +134,6 @@ size_t CrossPointWebServer::flushBufferToSD(size_t maxBytes) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
toWrite -= chunkLen;
|
toWrite -= chunkLen;
|
||||||
yield(); // Allow WiFi stack to process
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return totalWritten;
|
return totalWritten;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user