Richard Heathfield said:
Peter J. Holzer said:
"Wade Ward" <
[email protected]> a ?rit dans le message de (e-mail address removed)...
The benchmark to beat is eight minutes. Sleep on it.
[...]
given todays average harware performance, 1 minute seems a good goal
for this benchmark.
using fwrite with a decent buffer size should do it.
% ./heathfield > foo
please wait
./heathfield > foo 45.09s user 6.26s system 79% cpu 1:04.24 total
Looks like Richard's program reaches the goal even without fwrite.
Gosh!
That makes me wonder how fast I could make it if I were
actually trying to make it fast.
But of course it doesn't quite make me wonder *enough*...
Don't get carried away, if you are writing actual bytes to an actual hard
drive without tricks such as compression, delayed commit... The speed limit
is the drive throughput which averages 40-50 MB per second these days.
The timings show that your system is pretty busy running that loop popping
one byte at a time and checking its counter (79%) while we can assume the
hard drive does its flushing of memory buffers asynchronously.
Improving the code will mostly result in less user cpu time and more time
waiting for the drive.
If you have enough memory and set up a ram drive for this test, you should
get a 20% improvement and 100% cpu. Then you should see noticeable
improvements if you switch to a more efficient bufferisation:
using the program below, and limiting to 2g because of the file system, I
get the following benchmark:
$ time ./bigfile /tmp/toto 2147483647 0
real 0m48.271s
user 0m38.896s
sys 0m8.674s
$ time ./bigfile /tmp/toto 2147483647 8k
real 0m38.379s
user 0m0.463s
sys 0m9.286s
$ time ./bigfile /tmp/toto 2147483647 64k
real 0m34.771s
user 0m0.067s
sys 0m8.897s
$ time ./bigfile /tmp/toto 2147483647 1m
real 0m35.619s
user 0m0.023s
sys 0m9.109s
I can't test to a ram drive right now, but I would expect the overall time
to drop well below 10 seconds.
/* bigfile.c (C) Charlie Gordon 2007 */
/* Large file benchmark, placed in the public domain */
#include <stdio.h>
#include <stdlib.h>
long long getnumber(const char *str)
{
long long num = strtoll(str, (char **)&str, 0);
switch (*str) {
case 'g': return num << 30;
case 'm': return num << 20;
case 'k': return num << 10;
default: return num;
}
}
int main(int argc, char **argv)
{
FILE *fp;
long long file_size;
int buffer_size;
if (argc < 4) {
printf("usage: bigfile filename filesize buffersize\n");
return 0;
}
fp = fopen(argv[1], "wb");
file_size = getnumber(argv[2]);
buffer_size = getnumber(argv[3]);
if (buffer_size <= 0) {
while (file_size > 0) {
putc(0, fp);
file_size--;
}
} else {
char *buffer = calloc(buffer_size, 1);
while (file_size > 0) {
int written, towrite = buffer_size;
if (towrite > file_size)
towrite = file_size;
written = fwrite(buffer, 1, towrite, fp);
if (written <= 0) {
fclose(fp);
fprintf(stderr, "write error\n");
exit(EXIT_FAILURE);
}
file_size -= written;
}
}
fclose(fp);
return 0;
}