Skip to content

Commit 4b8a665

Browse files
committed
completed
0 parents  commit 4b8a665

14 files changed

Lines changed: 1131 additions & 0 deletions

File tree

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
build
2+
bin
3+
output
4+
data
5+
.vscode

Makefile

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#Makefile
2+
3+
CC=gcc
4+
CFLAGS = --std=c11 -O0 -DSF_VISIBILITY -fvisibility=hidden -fno-strict-aliasing
5+
6+
SRCDIR = src
7+
INCDIR = include
8+
BUILDDIR = build
9+
10+
TARGET = bin/cacher
11+
12+
SOURCES = $(wildcard $(SRCDIR)/*.c)
13+
14+
OBJECTS= $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(SOURCES:.c=.o))
15+
16+
INCLUDE = -I $(INCDIR)
17+
18+
all: $(TARGET)
19+
rebuild: all
20+
21+
debug: CFLAGS += -g
22+
debug: all
23+
24+
$(TARGET): $(OBJECTS)
25+
$(CC) $(CFLAGS) $^ -o $(TARGET)
26+
27+
$(BUILDDIR)/%.o: $(SRCDIR)/%.c
28+
@mkdir -p $(BUILDDIR)
29+
$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
30+
31+
clean:
32+
-rm -r $(BUILDDIR) $(TARGET)
33+
34+
.PHONY: clean

include/cache.h

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
#ifndef CACHE_H
2+
#define CACHE_H
3+
4+
#include <stdlib.h>
5+
6+
#include "map.h"
7+
#include "list.h"
8+
9+
typedef enum
10+
{
11+
LRU,
12+
ARC,
13+
LIRS
14+
} cache_type;
15+
16+
typedef struct
17+
{
18+
list *l;
19+
map *pages;
20+
int capacity;
21+
} cache_lru;
22+
23+
typedef struct
24+
{
25+
list *t1, *t2, *b1, *b2;
26+
map *ghosts, *pages;
27+
double p;
28+
int capacity;
29+
} cache_arc;
30+
31+
typedef struct
32+
{
33+
list *s, *q;
34+
map *ms, *mq;
35+
int Llirs;
36+
int Lhirs;
37+
int Lsize;
38+
int Hsize;
39+
int NRsize;
40+
41+
} cache_lirs;
42+
43+
typedef struct
44+
{
45+
46+
cache_type t;
47+
48+
union {
49+
cache_lru *lru;
50+
cache_arc *arc;
51+
cache_lirs *lirs;
52+
} data;
53+
54+
unsigned long requests;
55+
unsigned long hits;
56+
57+
} cache;
58+
59+
cache *cache_create(cache_type t, int capacity, int Lhirs_size);
60+
void cache_free(cache *c);
61+
62+
void cache_get(cache *c, int addr);
63+
void cache_print_stats(cache *c);
64+
65+
cache_lru *cache_lru_create(int capacity);
66+
int cache_lru_get(cache_lru *lru, int addr);
67+
void cache_lru_free(cache_lru *lru);
68+
69+
cache_lirs *cache_lirs_create(int capacity, int Lhirs_size);
70+
void stack_pruning(cache_lirs *lirs, list *l, map *m);
71+
int cache_lirs_get(cache_lirs *lirs, int addr);
72+
void cache_lirs_free(cache_lirs *lirs);
73+
74+
cache_arc *cache_arc_create(int capacity);
75+
void replace(cache_arc *arc, int addr);
76+
int cache_arc_get(cache_arc *arc, int addr);
77+
void cache_arc_free(cache_arc *arc);
78+
79+
#endif

include/list.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
#ifndef LIST_H
2+
#define LIST_H
3+
4+
#include <stdlib.h>
5+
6+
struct list;
7+
8+
typedef struct page {
9+
struct page *next;
10+
struct page *prev;
11+
struct list *l;
12+
int addr;
13+
int type; //for lirs, 1->Llirs, 2->Hlirs, 3->NR
14+
} page;
15+
16+
page *page_create (int addr);
17+
void page_free (page *p);
18+
19+
typedef struct list {
20+
page *head;
21+
page *tail;
22+
size_t size;
23+
} list;
24+
25+
list *list_create ();
26+
void list_free (list *l);
27+
page *list_remove (list *l, page *p);
28+
page *list_pop_back (list *l);
29+
void list_push_front (list *l, page *p);
30+
31+
#endif

include/map.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef MAP_H
2+
#define MAP_H
3+
4+
// default number of buckets
5+
#define MAP_NUM_BUCKET 1024
6+
7+
typedef struct bucket {
8+
int key;
9+
void *value;
10+
struct bucket *next;
11+
} bucket;
12+
13+
typedef struct {
14+
bucket **b; // array of bucket pointers
15+
size_t n; // number of buckets
16+
size_t size; // how many element are currently stored
17+
} map;
18+
19+
map *map_create();
20+
map *map_create_n(int n);
21+
void map_free(map *m);
22+
23+
void map_set(map *m, int key, void *value);
24+
void map_unset(map *m, int key);
25+
26+
void *map_get(map *m, int key);
27+
int map_has(map *m, int key);
28+
29+
#endif

script/parallel.sh

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#!/bin/bash
2+
3+
for number in {1..99..5}
4+
do
5+
./cacher $number 200000 ./traces/cb_web.trace >> outs/output"$number".txt &
6+
done
7+

script/test.sh

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
#!/bin/bash
2+
bin/cacher 1 15 data/msr_src2 4 > output/output1.txt
3+
for number in {5..100..5};
4+
do
5+
bin/cacher $number 15 data/msr_src2 3 > output/output$number.txt &
6+
done

src/arc.c

Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
#include "../include/cache.h"
2+
3+
cache_arc *cache_arc_create(int capacity)
4+
{
5+
cache_arc *arc = malloc(sizeof(cache_arc));
6+
7+
arc->t1 = list_create();
8+
arc->t2 = list_create();
9+
arc->b1 = list_create();
10+
arc->b2 = list_create();
11+
arc->pages = map_create_n(capacity);
12+
arc->ghosts = map_create_n(capacity);
13+
14+
arc->p = 0.0;
15+
arc->capacity = capacity;
16+
17+
return arc;
18+
}
19+
20+
void replace(cache_arc *arc, int addr)
21+
{
22+
page *ghost = map_get(arc->ghosts, addr);
23+
24+
if (arc->t1->size != 0 && // |t1| is not empty
25+
(arc->t1->size > arc->p || // |t1| exceeds target p
26+
(ghost != NULL && ghost->l == arc->b2 && // x_t is in b2
27+
arc->t1->size == arc->p)))
28+
{ // |t1| = p
29+
// delete LRU in t1
30+
page *p = list_pop_back(arc->t1);
31+
if (p != NULL)
32+
{
33+
// remove LRU from cache
34+
map_unset(arc->pages, p->addr);
35+
36+
// move lru into mru of b1
37+
list_push_front(arc->b1, p);
38+
map_set(arc->ghosts, p->addr, p);
39+
}
40+
}
41+
else
42+
{
43+
// delete LRU in t2
44+
page *p = list_pop_back(arc->t2);
45+
if (p != NULL)
46+
{
47+
// remove LRU from cache
48+
map_unset(arc->pages, p->addr);
49+
50+
// move lru into mru of b2
51+
list_push_front(arc->b2, p);
52+
map_set(arc->ghosts, p->addr, p);
53+
}
54+
}
55+
}
56+
57+
#define min(a, b) ((a < b) ? a : b)
58+
#define max(a, b) ((a > b) ? a : b)
59+
60+
#define sigma1(b1, b2) ((b1->size >= b2->size) ? 1 : b2->size / (double)b1->size)
61+
#define sigma2(b1, b2) ((b2->size >= b1->size) ? 1 : b1->size / (double)b2->size)
62+
63+
int cache_arc_get(cache_arc *arc, int addr)
64+
{
65+
66+
// Case I
67+
// page is in cache - hit
68+
// - in t1 or t2
69+
if (map_has(arc->pages, addr))
70+
{
71+
72+
page *p = map_get(arc->pages, addr);
73+
list_remove(p->l, p);
74+
list_push_front(arc->t2, p);
75+
76+
return 1;
77+
}
78+
79+
// Case II-III
80+
// page is in ghost cache
81+
if (map_has(arc->ghosts, addr))
82+
{
83+
page *p = map_get(arc->ghosts, addr);
84+
85+
// in b2
86+
if (p->l == arc->b1)
87+
{
88+
arc->p = min((arc->p + sigma1(arc->b1, arc->b2)), arc->capacity);
89+
// in b2
90+
}
91+
else
92+
{
93+
arc->p = max((arc->p - sigma2(arc->b1, arc->b2)), 0);
94+
}
95+
96+
replace(arc, addr);
97+
98+
// move page into lru of t2
99+
list_remove(p->l, p);
100+
list_push_front(arc->t2, p);
101+
102+
// fetch page into cache
103+
map_unset(arc->ghosts, addr);
104+
map_set(arc->pages, addr, p);
105+
106+
return 0;
107+
}
108+
109+
// Case IV
110+
111+
// - Case A
112+
if (arc->t1->size + arc->b1->size == arc->capacity)
113+
{
114+
if (arc->t1->size < arc->capacity)
115+
{
116+
page *p = list_pop_back(arc->b1);
117+
if (p != NULL)
118+
{
119+
map_unset(arc->ghosts, p->addr);
120+
page_free(p);
121+
}
122+
replace(arc, addr);
123+
}
124+
else
125+
{
126+
page *p = list_pop_back(arc->t1);
127+
if (p != NULL)
128+
{
129+
map_unset(arc->pages, p->addr);
130+
page_free(p);
131+
}
132+
}
133+
// - Case B
134+
}
135+
else
136+
{
137+
int len = arc->t1->size +
138+
arc->t2->size +
139+
arc->b1->size +
140+
arc->b2->size;
141+
if (len >= arc->capacity)
142+
{
143+
if (len == 2 * arc->capacity)
144+
{
145+
page *p = list_pop_back(arc->b2);
146+
if (p != NULL)
147+
{
148+
map_unset(arc->ghosts, p->addr);
149+
page_free(p);
150+
}
151+
}
152+
replace(arc, addr);
153+
}
154+
}
155+
156+
page *p = page_create(addr);
157+
list_push_front(arc->t1, p);
158+
map_set(arc->pages, addr, p);
159+
160+
return 0;
161+
}
162+
163+
void cache_arc_free(cache_arc *arc)
164+
{
165+
list_free(arc->t1);
166+
list_free(arc->t2);
167+
list_free(arc->b1);
168+
list_free(arc->b2);
169+
170+
map_free(arc->pages);
171+
map_free(arc->ghosts);
172+
173+
free(arc);
174+
}

0 commit comments

Comments
 (0)