contributed by <yusihlin
>
zhanyangch
$ gdb test_cpy
...
(gdb) run
...
choice: s
find words matching prefix (at least 1 char): A
Program received signal SIGSEGV, Segmentation fault.
0x0000000000401d81 in tst_suggest (p=0x12e1a30, c=65 'A', nchr=1,
a=0x7fffffffbc80, n=0x7fffffffbc40, max=1024) at tst.c:330
330 a[(*n)++] = (char *) p->eqkid;
choice: q
*** Error in `.../test_ref': free(): invalid pointer: 0x00007fffffffdd10 ***
執行 quit 會執行 tst_free_all,觀察內容發現它會 free tst_node 所儲存的字串
從 tst_ins_del 觀察 CPY 和 REF 的差異
tst_free_all 改為 tst_free
case 'q':
tst_free(root);
return 0;
break;
...
if (del) { /* delete instead of insert */
(curr->refcnt)--; /* decrement reference count */
/* chk refcnt, del 's', return NULL on successful del */
return tst_del_word(root, curr, &stk, cpy);
} else
curr->refcnt++; /* increment refcnt if word exists */
return (void *) curr->eqkid; /* pointer to word / NULL on del */
...
choice: s
find words matching prefix (at least 1 char): Tain
Tain - searched prefix in 0.000017 sec
suggest[0] : Tain
suggest[1] : Tain
suggest[2] : Tain
suggest[3] : Tain
suggest[4] : Tain
suggest[5] : Tain
suggest[6] : Tain
suggest[7] : Tain
suggest[8] : Tain
suggest[9] : Tain
suggest[10] : Tain
suggest[11] : Tain
enum { INS, DEL, WRDMAX = 256, STKMAX = 512, LMAX = 1024, CITYMAX = 260000 };
char (*city_space)[WRDMAX] = malloc(sizeof *city_space * CITYMAX);
while ((rtn = fscanf(fp, "%s", city_space[idx])) != EOF) {
char *p = city_space[idx];
/* FIXME: insert reference to each string */
if (!tst_ins_del(&root, &p, INS, REF)) {
fprintf(stderr, "error: memory exhausted, tst_insert.\n");
fclose(fp);
return 1;
}
idx++;
}
case 'a':
printf("enter word to add: ");
if (!fgets(city_space[idx], sizeof city_space[idx], stdin)) {
fprintf(stderr, "error: insufficient input.\n");
break;
}
rmcrlf(city_space[idx]);
p = city_space[idx];
...
case 'q':
tst_free(root);
free(city_space);
return 0;
break;
bench:
echo 3 | sudo tee /proc/sys/vm/drop_caches
perf stat --repeat 100 \
-e cache-misses,cache-references,instructions,cycles \
sudo chrt -f 99 taskset -c 0 ./test_cpy --bench
echo 3 | sudo tee /proc/sys/vm/drop_caches
perf stat --repeat 100 \
-e cache-misses,cache-references,instructions,cycles \
sudo chrt -f 99 taskset -c 0 ./test_ref --bench
if (argc == 2 && strcmp(argv[1], "--bench") == 0) {
/* build loading time txt */
fp = fopen (BENCH_LOAD_OUT,"a+");
if (!fp) {
fprintf(stderr, "error: file open failed in '%s'.\n", BENCH_LOAD_OUT);
return 1;
}
fprintf(fp, "%.6f\n",t2 - t1);
fclose(fp);
/* build searching time txt */
int r = bench_test(root, BENCH_SEARCH_OUT, sgl, &sidx, LMAX);
tst_free_all(root);
return r;
}
int bench_test(const tst_node *root,
char *search_out,
char **a,
int *n,
const int max)
{
char word[] = "A";
int i;
double t1, t2, search_time;
FILE *fp = fopen (search_out, "a+");
if (!fp) {
fprintf(stderr, "error: file open failed in '%s'.\n", search_out);
return 1;
}
for (i = 0; i < 25; i++) {
t1 = tvgetf();
tst_search_prefix(root, word, a, n, max);
t2 = tvgetf();
search_time += t2 - t1;
word[0]++;
}
word[0] = 'a';
for (i = 0; i < 25; i++) {
t1 = tvgetf();
tst_search_prefix(root, word, a, n, max);
t2 = tvgetf();
search_time += t2 - t1;
word[0]++;
}
fprintf(fp, "%.6f\n",search_time);
fclose(fp);
return 0;
}
Performance counter stats for 'sudo chrt -f 99 taskset -c 0 ./test_cpy --bench' (100 runs):
137 cache-misses # 24.244 % of all cache refs ( +- 11.26% )
567 cache-references ( +- 7.32% )
1,852 instructions # 0.40 insn per cycle ( +- 8.18% )
4,614 cycles ( +- 10.57% )
0.207701012 seconds time elapsed ( +- 3.43% )
Performance counter stats for 'sudo chrt -f 99 taskset -c 0 ./test_ref --bench' (100 runs):
110 cache-misses # 21.932 % of all cache refs ( +- 2.52% )
500 cache-references ( +- 0.76% )
1,676 instructions # 0.45 insn per cycle
3,743 cycles ( +- 2.19% )
0.225630593 seconds time elapsed ( +- 3.05% )
// Circular buffer object
typedef struct {
int size; // maximum number of elements
int start; // index of oldest element
unsigned int end; // index at which to write new element
char *elems; // vector of elements
} CircularBuffer;
void cbInit(CircularBuffer *cb, int size) {
cb->size = size;
cb->start = 0;
cb->end = 0;
cb->elems = (char *)calloc(cb->size, sizeof(char));
}
/* start store from the middle */
buffer.start = CircularBufferSize >> 1;
buffer.end = CircularBufferSize >> 1;
buffer_head += (CircularBufferSize >> 1);
while ((rtn = fscanf(fp, "%s", buffer_head)) != EOF) {
char *p = buffer_head;
/* FIXME: insert reference to each string */
if (!tst_ins_del(&root, &p, INS, REF)) {
fprintf(stderr, "error: memory exhausted, tst_insert.\n");
fclose(fp);
return 1;
}
idx++;
int word_len = strlen(buffer_head) + 1;
if( WRDMAX + buffer.end >= CircularBufferSize) {
buffer_head -= buffer.end;
buffer.end = 0;
} else {
buffer.end = word_len + buffer.end;
buffer_head += word_len;
}
}
Breakpoint 1,...
(gdb) p buffer.start
$1 = 1500000
(gdb) p buffer.end
$2 = 679425
(gdb) p buffer.elems+1500000
$3 = 0x7ffff789e370 "Shanghai,"
(gdb) p buffer.elems+2999750
$4 = 0x7ffff7a0c5d6 "Belaya"
(gdb) p buffer.elems
$5 = 0x7ffff7730010 "Gora,"
Performance counter stats for 'sudo chrt -f 99 taskset -c 0 ./test_cpy --bench' (100 runs):
116 cache-misses # 22.543 % of all cache refs ( +- 3.40% )
513 cache-references ( +- 1.56% )
1,688 instructions # 0.42 insn per cycle ( +- 0.72% )
4,036 cycles ( +- 3.10% )
0.211468978 seconds time elapsed ( +- 3.76% )
Performance counter stats for 'sudo chrt -f 99 taskset -c 0 ./test_ref --bench' (100 runs):
126 cache-misses # 23.132 % of all cache refs ( +- 8.87% )
543 cache-references ( +- 5.52% )
1,830 instructions # 0.41 insn per cycle ( +- 8.40% )
4,471 cycles ( +- 8.84% )
0.221327696 seconds time elapsed ( +- 5.16% )
不要只貼網址,要把參照的文件/論文標題寫出來
"jserv"
已修正
"yusihlin"