Skip to content

Commit c9f6a6c

Browse files
author
Margo Seltzer
committed
In-class exercises
1 parent 75f7d00 commit c9f6a6c

File tree

6 files changed

+184
-0
lines changed

6 files changed

+184
-0
lines changed

storage2/Makefile

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
PROGRAMS = w01_sync w02_syscall w03_stdio
2+
3+
INCLUDES = -I.
4+
5+
CFLAGS = -g -O3 -Wall -std=gnu11 $(INCLUDES)
6+
7+
all: $(PROGRAMS)
8+
9+
%.o:%.c
10+
$(CC) $(CFLAGS) -c $<
11+
12+
w01_sync: w01_sync.o
13+
$(CC) $(CFLAGS) -o $@ w01_sync.o
14+
15+
w02_syscall: w02_syscall.o
16+
$(CC) $(CFLAGS) -o $@ w02_syscall.o
17+
18+
w03_stdio: w03_stdio.o
19+
$(CC) $(CFLAGS) -o $@ w03_stdio.o
20+
21+
clean:
22+
rm -f $(PROGRAMS) *.o core a.out data

storage2/README.txt

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
Beginning of cache exercises. It's possible that some of the performance
2+
differences illustrated here will not be apparent in the appliance, so
3+
you may need/want to run them directly on your laptop/desktop. They are
4+
relatively simple programs that should translate easily.
5+
6+
w01 (super slow) O_WRONLY | O_CREAT | O_TRUNC | O_SYNC (1 byte/write)
7+
w02 (quick) O_WRONLY | O_CREAT | O_TRUNC (1 byte/write)
8+
w03 (super quick) stdio (1 byte/write)
9+

storage2/iobench.h

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
#ifndef IOBENCH_H
2+
#define IOBENCH_H
3+
4+
#define _GNU_SOURCE 1
5+
#include <unistd.h>
6+
#include <sys/types.h>
7+
#include <sys/stat.h>
8+
#include <fcntl.h>
9+
#include <stdio.h>
10+
#include <stdlib.h>
11+
#include <assert.h>
12+
#include <string.h>
13+
#include <limits.h>
14+
#include <sys/time.h>
15+
16+
static inline double tstamp(void) {
17+
struct timeval tv;
18+
gettimeofday(&tv, 0);
19+
return tv.tv_sec + tv.tv_usec / 1000000.;
20+
}
21+
22+
// Print a report to stderr of # bytes printed, elapsed time, and rate.
23+
static inline void report(size_t n, double elapsed) {
24+
fprintf(stderr, "\r%zd bytes %g sec %g byte/sec ",
25+
n, elapsed, n / elapsed);
26+
}
27+
28+
// Return the size of a file.
29+
static inline ssize_t filesize(int fd) {
30+
struct stat s;
31+
int r = fstat(fd, &s);
32+
if (r >= 0 && S_ISREG(s.st_mode) && s.st_size <= SSIZE_MAX)
33+
return s.st_size;
34+
else
35+
return -1;
36+
}
37+
38+
#ifndef PRINT_FREQUENCY
39+
#define PRINT_FREQUENCY 4096
40+
#endif
41+
42+
#endif

storage2/w01_sync.c

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include "iobench.h"
2+
3+
int main() {
4+
int fd = STDOUT_FILENO;
5+
if (isatty(fd))
6+
fd = open("data", O_WRONLY | O_CREAT | O_TRUNC | O_SYNC, 0666);
7+
if (fd < 0) {
8+
perror("open");
9+
exit(1);
10+
}
11+
/*
12+
* All the other benchmarks use a size of approximately 5 MB, however,
13+
* this benchmark is painfully slow and trying to write that much will
14+
* take too long, so we reduce it by a factor of 100.
15+
*/
16+
// size_t size = 5120000;
17+
size_t size = 51200;
18+
const char *buf = "6";
19+
double start = tstamp();
20+
21+
size_t n = 0;
22+
while (n < size) {
23+
// Write 1 character at a time, using the write system call.
24+
ssize_t r = write(fd, buf, 1);
25+
if (r != 1) {
26+
perror("write");
27+
exit(1);
28+
}
29+
n += r;
30+
if (n % PRINT_FREQUENCY == 0)
31+
report(n, tstamp() - start);
32+
}
33+
34+
close(fd);
35+
report(n, tstamp() - start);
36+
fprintf(stderr, "\n");
37+
}

storage2/w02_syscall.c

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include "iobench.h"
2+
3+
int main() {
4+
int fd = STDOUT_FILENO;
5+
if (isatty(fd))
6+
fd = open("data", O_WRONLY | O_CREAT | O_TRUNC, 0666);
7+
if (fd < 0) {
8+
perror("open");
9+
exit(1);
10+
}
11+
12+
/*
13+
* All the other benchmarks use a size of approximately 5 MB, however,
14+
* this benchmark is painfully slow and trying to write that much will
15+
* take too long, so we reduce it by a factor of 100.
16+
*/
17+
// size_t size = 5120000;
18+
size_t size = 51200;
19+
const char* buf = "6";
20+
double start = tstamp();
21+
22+
size_t n = 0;
23+
while (n < size) {
24+
ssize_t r = write(fd, buf, 1);
25+
if (r != 1) {
26+
perror("write");
27+
exit(1);
28+
}
29+
n += r;
30+
if (n % PRINT_FREQUENCY == 0)
31+
report(n, tstamp() - start);
32+
}
33+
34+
close(fd);
35+
report(n, tstamp() - start);
36+
fprintf(stderr, "\n");
37+
}

storage2/w03_stdio.c

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include "iobench.h"
2+
3+
int main() {
4+
FILE* f = stdout;
5+
if (isatty(fileno(f)))
6+
f = fopen("data", "w");
7+
if (!f) {
8+
perror("fopen");
9+
exit(1);
10+
}
11+
12+
/*
13+
* All the other benchmarks use a size of approximately 5 MB, however,
14+
* this benchmark is painfully slow and trying to write that much will
15+
* take too long, so we reduce it by a factor of 100.
16+
*/
17+
// size_t size = 5120000;
18+
size_t size = 51200;
19+
const char* buf = "6";
20+
double start = tstamp();
21+
22+
size_t n = 0;
23+
while (n < size) {
24+
size_t r = fwrite(buf, 1, 1, f);
25+
if (r != 1) {
26+
perror("write");
27+
exit(1);
28+
}
29+
n += r;
30+
if (n % PRINT_FREQUENCY == 0)
31+
report(n, tstamp() - start);
32+
}
33+
34+
fclose(f);
35+
report(n, tstamp() - start);
36+
fprintf(stderr, "\n");
37+
}

0 commit comments

Comments
 (0)