Skip to content
This repository was archived by the owner on Sep 10, 2022. It is now read-only.

Reduce phonebook_opt.h entry size #3

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
add hash fuction
Weinux committed Sep 28, 2016
commit dbaa9637d4612f28b649b1492dc50dd6107b6b00
105 changes: 61 additions & 44 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,45 +1,62 @@
CC ?= gcc
CFLAGS_common ?= -Wall -std=gnu99
CFLAGS_orig = -O0
CFLAGS_opt = -O0

EXEC = phonebook_orig phonebook_opt
all: $(EXEC)

SRCS_common = main.c

phonebook_orig: $(SRCS_common) phonebook_orig.c phonebook_orig.h
$(CC) $(CFLAGS_common) $(CFLAGS_orig) \
-DIMPL="\"$@.h\"" -o $@ \
$(SRCS_common) $@.c

phonebook_opt: $(SRCS_common) phonebook_opt.c phonebook_opt.h
$(CC) $(CFLAGS_common) $(CFLAGS_opt) \
-DIMPL="\"$@.h\"" -o $@ \
$(SRCS_common) $@.c

run: $(EXEC)
echo 3 | sudo tee /proc/sys/vm/drop_caches
watch -d -t "./phonebook_orig && echo 3 | sudo tee /proc/sys/vm/drop_caches"

cache-test: $(EXEC)
perf stat --repeat 100 \
-e cache-misses,cache-references,instructions,cycles \
./phonebook_orig
perf stat --repeat 100 \
-e cache-misses,cache-references,instructions,cycles \
./phonebook_opt

output.txt: cache-test calculate
./calculate

plot: output.txt
gnuplot scripts/runtime.gp

calculate: calculate.c
$(CC) $(CFLAGS_common) $^ -o $@

.PHONY: clean
clean:
$(RM) $(EXEC) *.o perf.* \
calculate orig.txt opt.txt output.txt runtime.png
CFLAGS_common ?= -g -Wall -std=gnu99
CFLAGS_orig = -O0
CFLAGS_opt = -O0
CFLAGS_hash = -O0



EXEC = phonebook_orig phonebook_opt phonebook_hash
all: $(EXEC)

SRCS_common = main.c

phonebook_orig: $(SRCS_common) phonebook_orig.c phonebook_orig.h
$(CC) $(CFLAGS_common) $(CFLAGS_orig) \
-DIMPL="\"$@.h\"" -o $@ \
$(SRCS_common) $@.c

phonebook_opt: $(SRCS_common) phonebook_opt.c phonebook_opt.h
$(CC) $(CFLAGS_common) $(CFLAGS_opt) \
-DIMPL="\"$@.h\"" -o $@ \
$(SRCS_common) $@.c

phonebook_hash: $(SRCS_common) phonebook_hash.c phonebook_hash.h
$(CC) $(CFLAGS_common) $(CFLAGS_hash) \
-DIMPL="\"$@.h\"" -o $@ \
$(SRCS_common) $@.c





run: $(EXEC)
echo 3 | sudo tee /proc/sys/vm/drop_caches
watch -d -t "./phonebook_orig && echo 3 | sudo tee /proc/sys/vm/drop_caches"

cache-test: $(EXEC)
perf stat --repeat 100 \
-e cache-misses,cache-references,instructions,cycles \
./phonebook_orig
perf stat --repeat 100 \
-e cache-misses,cache-references,instructions,cycles \
./phonebook_opt
perf stat --repeat 100 \
-e cache-misses,cache-references,instructions,cycles \
./phonebook_hash



output.txt: cache-test calculate
./calculate

plot: output.txt
gnuplot scripts/runtime.gp

calculate: calculate.c
$(CC) $(CFLAGS_common) $^ -o $@

.PHONY: clean
clean:
$(RM) $(EXEC) *.o perf.* \
calculate orig.txt opt.txt output.txt runtime.png
27 changes: 25 additions & 2 deletions calculate.c
Original file line number Diff line number Diff line change
@@ -43,8 +43,31 @@ int main(void)
opt_sum_a += opt_a;
opt_sum_f += opt_f;
}
fprintf(output, "append() %lf %lf\n",orig_sum_a / 100.0, opt_sum_a / 100.0);
fprintf(output, "findName() %lf %lf", orig_sum_f / 100.0, opt_sum_f / 100.0);

fp = fopen("hash.txt", "r");
if (!fp) {
fp = fopen("opt.txt", "r");
if (!fp) {
printf("ERROR opening input file hash1.txt\n");
exit(0);
}
}

double hash_sum_a = 0.0, hash_sum_f = 0.0, hash_a, hash_f;
for (i = 0; i < 100; i++) {
if (feof(fp)) {
printf("ERROR: You need 100 datum instead of %d\n", i);
printf("run 'make run' longer to get enough information\n\n");
exit(0);
}
fscanf(fp, "%s %s %lf %lf\n", append, find,&hash_a, &hash_f);
hash_sum_a += hash_a;
hash_sum_f += hash_f;
}


fprintf(output, "append() %lf %lf %lf\n",orig_sum_a / 100.0, opt_sum_a / 100.0, hash_sum_a/100 );
fprintf(output, "findName() %lf %lf %lf", orig_sum_f / 100.0, opt_sum_f / 100.0, hash_sum_f/100 );
fclose(output);
fclose(fp);
return 0;
1,025 changes: 1,025 additions & 0 deletions hash.txt

Large diffs are not rendered by default.

44 changes: 42 additions & 2 deletions main.c
Original file line number Diff line number Diff line change
@@ -35,13 +35,23 @@ int main(int argc, char *argv[])
printf("cannot open the file\n");
return -1;
}

#if defined (HASH)
entry *pHead[SIZE],*e[SIZE]; //malloc pHead[],use e[] to point pHead[]
printf("size of entry : %lu bytes\n", sizeof(entry));
for(i=0; i<SIZE; ++i) { //why?
pHead[i]=(entry *) malloc(sizeof(entry));
e[i]=pHead[i];
e[i]->pNext=NULL;
}
#else
/* build the entry */
entry *pHead, *e;
pHead = (entry *) malloc(sizeof(entry));
printf("size of entry : %lu bytes\n", sizeof(entry));
e = pHead;
e->pNext = NULL;
#endif


#if defined(__GNUC__)
__builtin___clear_cache((char *) pHead, (char *) pHead + sizeof(entry));
@@ -52,19 +62,35 @@ int main(int argc, char *argv[])
i++;
line[i - 1] = '\0';
i = 0;
#if defined (HASH)
append(line,e);
#else
e = append(line, e);
#endif





}
clock_gettime(CLOCK_REALTIME, &end);
cpu_time1 = diff_in_second(start, end);

/* close file as soon as possible */
fclose(fp);

#if defined (HASH)
for(i=0; i<SIZE; ++i) {
e[i] = pHead[i];
}
#else
e = pHead;
#endif


/* the givn last name to find */
char input[MAX_LAST_NAME_SIZE] = "zyxel";
e = pHead;
// e = pHead;

assert(findName(input, e) &&
"Did you implement findName() in " IMPL "?");
@@ -82,17 +108,31 @@ int main(int argc, char *argv[])
FILE *output;
#if defined(OPT)
output = fopen("opt.txt", "a");
#elif defined(HASH)
output = fopen("hash.txt","a");
#else
output = fopen("orig.txt", "a");

#endif
fprintf(output, "append() findName() %lf %lf\n", cpu_time1, cpu_time2);
fclose(output);

printf("execution time of append() : %lf sec\n", cpu_time1);
printf("execution time of findName() : %lf sec\n", cpu_time2);



#if defined(HASH)
for(i=0; i<SIZE; ++i) {
if(pHead[i]->pNext) {
Free_List(pHead[i]);
pHead[i] = NULL;
}
}
#else
if (pHead->pNext) free(pHead->pNext);
free(pHead);
#endif

return 0;
}
Binary file added phonebook_hash
Binary file not shown.
63 changes: 63 additions & 0 deletions phonebook_hash.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#include "phonebook_hash.h"

/* FILL YOUR OWN IMPLEMENTATION HERE! */
entry *findName(char lastname[], entry *e[])
{
/* TODO: implement */
entry *tmp;
unsigned int n = BKDRHash(lastname);
/*judge if e[n] has value*/
if(e[n]->pNext) {
tmp = e[n]->pNext;
} else return NULL;
/*findname*/
while(tmp) {
if (strcasecmp(lastname, tmp->lastName) == 0)
return tmp;
tmp = tmp->pNext;
}
return NULL;
}

void append(char lastName[], entry *e[])
{
entry *tmp;
unsigned int n=BKDRHash(lastName);
/*if e[n] has no data*/
if (e[n]->pNext== NULL) tmp = e[n];
else tmp = e[n]->pNext;
tmp->pNext = (entry *) malloc(sizeof(entry));
tmp = tmp->pNext;
strcpy(tmp->lastName, lastName);
tmp->pNext = NULL;
e[n]=tmp;
}

unsigned int BKDRHash(char lastName[])
{
unsigned int seed=31;
unsigned int hash=0;
int i=0;
while(i<strlen(lastName)) {
hash = hash * seed + lastName[i++];

}

return hash %= SIZE;
}

void Free_List(entry *e)
{
entry *tmp;
while(e) {
tmp = e->pNext;
free(e);
e = tmp;
}
}

31 changes: 31 additions & 0 deletions phonebook_hash.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#ifndef _PHONEBOOK_H
#define _PHONEBOOK_H
#define HASH 1
#define MAX_LAST_NAME_SIZE 16
#define SIZE 3701

typedef struct __PHONE_BOOK_DETAIL {
char firstName[16];
char email[16];
char phone[10];
char cell[10];
char addr1[16];
char addr2[16];
char city[16];
char state[2];
char zip[5];
} detail;



typedef struct __PHONE_BOOK_ENTRY {
char lastName[MAX_LAST_NAME_SIZE];
detail *pDetail;
struct __PHONE_BOOK_ENTRY *pNext;
} entry;

entry *findName(char lastname[], entry *e[]);
void append(char lastName[], entry *e[]);
void Free_List(entry *e);
unsigned int BKDRHash(char *str);
#endif
5 changes: 4 additions & 1 deletion scripts/runtime.gp
Original file line number Diff line number Diff line change
@@ -8,4 +8,7 @@ set output 'runtime.png'
plot [:][:0.150]'output.txt' using 2:xtic(1) with histogram title 'original', \
'' using ($0-0.06):($2+0.001):2 with labels title ' ', \
'' using 3:xtic(1) with histogram title 'optimized' , \
'' using ($0+0.3):($3+0.0015):3 with labels title ' '
'' using 4:xtic(1) with histogram title 'hash' , \
'' using ($0+0.3):($3+0.0015):3 with labels title ' ', \
'' using ($0+0.4):($4+0.0015):4 with labels title ' '