Reducing Seek Overhead with Application-Directed Prefetching
Steve VanDeBogart, Christopher Frost, Eddie Kohler University of California, Los Angeles http://libprefetch.cs.ucla.edu
Reducing Seek Overhead with Application-Directed Prefetching Steve - - PowerPoint PPT Presentation
Reducing Seek Overhead with Application-Directed Prefetching Steve VanDeBogart, Christopher Frost, Eddie Kohler University of California, Los Angeles http://libprefetch.cs.ucla.edu Disks are Relatively Slow Average Throughput Whetstone Seek
Steve VanDeBogart, Christopher Frost, Eddie Kohler University of California, Los Angeles http://libprefetch.cs.ucla.edu
2
3
4
5
6
7
8
9
10
11
12
1
→6 →2 →8 →4 →7
CPU I/O Time
13
1
→6 →2 →8 →4 →7
CPU I/O 1 →6 →2 →8 →4 →7
CPU I/O Time
14
1
→6 →2 →8 →4 →7
CPU I/O 1 →6 →2 →8 →4 →7
CPU I/O 1 →6 →2 →8 →4 →7
CPU I/O Time
15
16
17
6 2 1 4 7 8 6 1 2 4 7 8
18
1 1 →4 8 4 2 6 →2 1 →6 →7 →8 7 CPU Dependency I/O 1 →6 1 →2 →8 →4 →7 6 2 8 4 7 CPU Dependency I/O Time
19
1 →6 →2 →8 →4 →7
CPU I/O Time 1 →6 →4 →7 8
CPU I/O 2 1 →4 7 8
CPU I/O 2 →6
20
21
22
23
24
25
26
27
28
c = register_client(callback, NULL);
450 450
29
c = register_client(callback, NULL); r1 = register_region(c, A, 75, 350); r2 = register_region(c, B, 100, 200); r3 = register_region(c, B, 300, 400);
450 100 200 300 400 75 350 450
30
c = register_client(callback, NULL); r1 = register_region(c, A, 75, 350); r2 = register_region(c, B, 100, 200); r3 = register_region(c, B, 300, 400); a_list = { {A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1} }; n = request_prefetching(c, a_list, 3, PF_SET ¦ PF_DONE);
450 100 200 300 400 75 350 450
31
c = register_client(callback, NULL); r1 = register_region(c, A, 75, 350); r2 = register_region(c, B, 100, 200); r3 = register_region(c, B, 300, 400); a_list = { {A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1} }; n = request_prefetching(c, a_list, 3, PF_SET ¦ PF_DONE); Access list entry: file descriptor, file offset, marked flag
450 100 200 300 400 75 350 450
32
c = register_client(callback, NULL); r1 = register_region(c, A, 75, 350); r2 = register_region(c, B, 100, 200); r3 = register_region(c, B, 300, 400); a_list = { {A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1} }; n = request_prefetching(c, a_list, 3, PF_SET ¦ PF_DONE); Flags: append, clear, complete
450 100 200 300 400 75 350 450
33
c = register_client(callback, NULL); r1 = register_region(c, A, 75, 350); r2 = register_region(c, B, 100, 200); r3 = register_region(c, B, 300, 400); a_list = { {A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1} }; n = request_prefetching(c, a_list, 3, PF_SET ¦ PF_DONE); Accepted entries “short” = full
450 100 200 300 400 75 350 450
34
c = register_client(callback, NULL); r1 = register_region(c, A, 75, 350); r2 = register_region(c, B, 100, 200); r3 = register_region(c, B, 300, 400); a_list = { {A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1} }; n = request_prefetching(c, a_list, 3, PF_SET ¦ PF_DONE); libprefetch_a_list = {{A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1}};
450 100 200 300 400 75 350 450
fadvise(A, 100, WILL_NEED) … fadvise(B, 150, WILL_NEED) … fadvise(A, 200, WILL_NEED)
35
c = register_client(callback, NULL); r1 = register_region(c, A, 75, 350); r2 = register_region(c, B, 100, 200); r3 = register_region(c, B, 300, 400); a_list = { {A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1} }; n = request_prefetching(c, a_list, 3, PF_SET ¦ PF_DONE); pread(A, ..., 100);
450 100 200 300 400 75 350 450
libprefetch_a_list = {{A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1}};
36
c = register_client(callback, NULL); r1 = register_region(c, A, 75, 350); r2 = register_region(c, B, 100, 200); r3 = register_region(c, B, 300, 400); a_list = { {A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1} }; n = request_prefetching(c, a_list, 3, PF_SET ¦ PF_DONE); pread(A, ..., 100);
450 100 200 300 400 75 350 450
libprefetch_a_list = {{A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1}}; Check access list Check in memory fincore(A, 100, ...)
37
c = register_client(callback, NULL); r1 = register_region(c, A, 75, 350); r2 = register_region(c, B, 100, 200); r3 = register_region(c, B, 300, 400); a_list = { {A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1} }; n = request_prefetching(c, a_list, 3, PF_SET ¦ PF_DONE); pread(A, ..., 100); ... pread(B, ..., 350);
450 100 200 300 400 75 350 450
Access list doesn't
into application to update it. libprefetch_a_list = {{A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1}};
38
c = register_client(callback, NULL); r1 = register_region(c, A, 75, 350); r2 = register_region(c, B, 100, 200); r3 = register_region(c, B, 300, 400); a_list = { {A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1} }; n = request_prefetching(c, a_list, 3, PF_SET ¦ PF_DONE); pread(A, ..., 100); ... pread(B, ..., 350);
450 100 200 300 400 75 350 450
void callback(void* arg, int markedFD, loff_t markedOffset, int requestedFD, loff_t requestedOffset); libprefetch_a_list = {{A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1}};
39
c = register_client(callback, NULL); r1 = register_region(c, A, 75, 350); r2 = register_region(c, B, 100, 200); r3 = register_region(c, B, 300, 400); a_list = { {A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1} }; n = request_prefetching(c, a_list, 3, PF_SET ¦ PF_DONE); pread(A, ..., 100); ... pread(B, ..., 350);
450 100 200 300 400 75 350 450
void callback(NULL, A, 100, B, 350) { a_list = compute_new_alist(B, 350); n = request_prefetching(c, a_list, 2, PF_SET ¦ PF_DONE); } libprefetch_a_list = {{A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1}};
40
c = register_client(callback, NULL); r1 = register_region(c, A, 75, 350); r2 = register_region(c, B, 100, 200); r3 = register_region(c, B, 300, 400); a_list = { {A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1} }; n = request_prefetching(c, a_list, 3, PF_SET ¦ PF_DONE); pread(A, ..., 100); ... pread(B, ..., 350);
450 100 200 300 400 75 350 450
void callback(NULL, A, 100, B, 350) { a_list = compute_new_alist(B, 350); n = request_prefetching(c, a_list, 2, PF_SET ¦ PF_DONE); } libprefetch_a_list = {{B, 150, 0}, ... {A, 200, 1}};
41
c = register_client(callback, NULL); r1 = register_region(c, A, 75, 350); r2 = register_region(c, B, 100, 200); r3 = register_region(c, B, 300, 400); a_list = { {A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1} }; n = request_prefetching(c, a_list, 3, PF_SET ¦ PF_DONE); pread(A, ..., 100); ... pread(B, ..., 350); ... pread(A, ..., 400);
450 100 200 300 400 75 350 450
libprefetch_a_list = {{B, 150, 0}, ... {A, 200, 1}};
42
c = register_client(callback, NULL); r1 = register_region(c, A, 75, 350); r2 = register_region(c, B, 100, 200); r3 = register_region(c, B, 300, 400); a_list = { {A, 100, 1}, ... {B, 150, 0}, ... {A, 200, 1} }; n = request_prefetching(c, a_list, 3, PF_SET ¦ PF_DONE); pread(A, ..., 100); ... pread(B, ..., 350); ... pread(A, ..., 400); pread(A, ..., 200);
450 100 200 300 400 75 350 450
End of access list, callback to get more information. libprefetch_a_list = {{B, 150, 0}, ... {A, 200, 1}};
43
44
45
46
47
48
49
RAM
50
51
52
53
54
55
56
57
58