flush() does the same thing as close() except for marking the file closed. This requires writing many file structures, not just the cached data.
You don't need to call flush unless there is a chance of your program crashing before you close the file.
Here is a simple program that writes 524,288 byte (1024 blocks on the SD).
It uses buffer sizes of 1, 2, 4, 8, 16, 32, 64, 128, 256, and 512 bytes.
#define SD_CS_PIN SS
#define TEST_FILE_NAME "testfile.txt"
// 1024 block file
#define FILE_SIZE 1024UL*512UL
#include <SPI.h>
// use next line to test SD.h
//#include <SD.h>
// use next two lines to test SdFat
#include "SdFat.h"
SdFat SD;
uint8_t buf[512];
File myFile;
void setup() {
// Open serial communications and wait for port to open:
Serial.begin(9600);
// Wait for USB Serial
while (!Serial) {
}
if (!SD.begin(SD_CS_PIN)) {
Serial.println("SD.begin failed!");
return;
}
for (size_t n = 1; n <= 512; n *= 2) {
SD.remove(TEST_FILE_NAME);
myFile = SD.open(TEST_FILE_NAME, FILE_WRITE);
if (!myFile) {
Serial.println("open failed");
return;
}
// Write file data
uint32_t us = micros();
for (uint32_t i = 0; i < FILE_SIZE; i += n) {
if (n != myFile.write(buf, n)) {
Serial.println("Write failed");
return;
}
}
us = micros() - us;
myFile.close();
Serial.print("buffer size (bytes): ");
Serial.print(n);
Serial.print(", time (sec): ");
Serial.print(0.000001*us);
Serial.print(", rate (KB/sec): ");
Serial.println(FILE_SIZE / (0.001 * us));
}
}
void loop() {
// nothing happens after setup
}
Here are the results of running it with the SD.h library. SD.h uses a very old version of SdFat at slow SPI speed.
buffer size (bytes): 1, time (sec): 22.21, rate (KB/sec): 23.61
buffer size (bytes): 2, time (sec): 12.78, rate (KB/sec): 41.01
buffer size (bytes): 4, time (sec): 8.21, rate (KB/sec): 63.82
buffer size (bytes): 8, time (sec): 5.79, rate (KB/sec): 90.60
buffer size (bytes): 16, time (sec): 4.61, rate (KB/sec): 113.76
buffer size (bytes): 32, time (sec): 4.05, rate (KB/sec): 129.52
buffer size (bytes): 64, time (sec): 3.73, rate (KB/sec): 140.38
buffer size (bytes): 128, time (sec): 3.61, rate (KB/sec): 145.22
buffer size (bytes): 256, time (sec): 3.52, rate (KB/sec): 149.12
buffer size (bytes): 512, time (sec): 3.08, rate (KB/sec): 170.24
Here is the result with a new version of SdFat.
buffer size (bytes): 1, time (sec): 18.26, rate (KB/sec): 28.71
buffer size (bytes): 2, time (sec): 9.75, rate (KB/sec): 53.76
buffer size (bytes): 4, time (sec): 5.46, rate (KB/sec): 96.02
buffer size (bytes): 8, time (sec): 3.33, rate (KB/sec): 157.32
buffer size (bytes): 16, time (sec): 2.27, rate (KB/sec): 230.65
buffer size (bytes): 32, time (sec): 1.76, rate (KB/sec): 297.35
buffer size (bytes): 64, time (sec): 1.66, rate (KB/sec): 315.02
buffer size (bytes): 128, time (sec): 1.72, rate (KB/sec): 304.76
buffer size (bytes): 256, time (sec): 1.69, rate (KB/sec): 309.48
buffer size (bytes): 512, time (sec): 1.59, rate (KB/sec): 329.91
There is little gain in speed after a buffer size of 32 bytes. For a one bytes buffer, the rate is 28.71 KB/sec so the time to write a single byte is about 0.035 ms.
For a 32 byte buffer the rate is 297.35 KB/sec or 0.0034 ms per byte.
Note the slight increase in speed for 512 byte writes. SdFat does not cache these writes since they can be directly written to the SD. This is only possible when writing a full SD block and the file position is on a block boundary.