Adding a nominal stage 4.

This commit is contained in:
Geoff Langdale 2018-05-03 21:42:16 +10:00
parent 237d83885d
commit e78e7687d6
1 changed files with 141 additions and 8 deletions

149
main.cpp
View File

@ -360,11 +360,11 @@ const u32 char_control[256] = {
// 0x5b/5d are []
CDF,CDF,CDF,CDF, CDF,CDF,CDF,CDF, CDF,CDF,CDF,CP8, CDF,CM8,CDF,CDF,
// nothing interesting from 0x60-0x69
CDF,CDF,CDF,CDF, CDF,CDF,CDF,CDF, CDF,CDF,CDF,CDF, CDF,CDF,CDF,CDF,
// f is 0x66 n is 0x6e
CDF,CDF,CDF,CDF, CDF,CDF,C08,CDF, CDF,CDF,CDF,CDF, CDF,CDF,C08,CDF,
// 0x7b/7d are {}
CDF,CDF,CDF,CDF, CDF,CDF,CDF,CDF, CDF,CDF,CDF,CP8, CDF,CM8,CDF,CDF,
// 0x7b/7d are {}, 74 is t
CDF,CDF,CDF,CDF, C08,CDF,CDF,CDF, CDF,CDF,CDF,CP8, CDF,CM8,CDF,CDF,
// nothing interesting from 0x80-0xff
CDF,CDF,CDF,CDF, CDF,CDF,CDF,CDF, CDF,CDF,CDF,CDF, CDF,CDF,CDF,CDF,
@ -380,6 +380,7 @@ const u32 char_control[256] = {
const size_t MAX_TAPE_ENTRIES = 1024*1024;
const size_t MAX_TAPE = MAX_DEPTH * MAX_TAPE_ENTRIES;
u32 tape[MAX_TAPE];
u32 tape_locs[MAX_DEPTH];
// STATE MACHINE DECLARATIONS
@ -454,7 +455,6 @@ never_inline bool ape_machine(const u8 * buf, UNUSED size_t len, ParsedJson & pj
// moved from their starting values)
u32 depth = 1;
u32 tape_locs[MAX_DEPTH];
for (u32 i = 0; i < MAX_DEPTH; i++) {
tape_locs[i] = i*MAX_TAPE_ENTRIES;
@ -534,6 +534,121 @@ never_inline bool ape_machine(const u8 * buf, UNUSED size_t len, ParsedJson & pj
return true;
}
u32 count_tapes;
u32 count_opens;
u32 count_strings;
u32 count_non_zeros;
u32 count_leading_zeros;
u32 count_minus;
u32 count_true;
u32 count_false;
u32 count_null;
// they are { 0x7b } 0x7d : 0x3a [ 0x5b ] 0x5d , 0x2c
// these go into the first 3 buckets of the comparison (1/2/4)
// we are also interested in the four whitespace characters
// space 0x20, linefeed 0x0a, horizontal tab 0x09 and carriage return 0x0d
const u32 structural_or_whitespace_negated[256] = {
1,1,1,1, 1,1,1,1, 1,0,0,1, 1,0,1,1,
1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
0,1,1,1, 1,1,1,1, 1,1,1,1, 0,1,1,1,
1,1,1,1, 1,1,1,1, 1,1,0,1, 1,1,1,1,
1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
1,1,1,1, 1,1,1,1, 1,1,1,0, 1,0,1,1,
1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
1,1,1,1, 1,1,1,1, 1,1,1,0, 1,0,1,1,
1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1,
1,1,1,1, 1,1,1,1, 1,1,1,1, 1,1,1,1
};
// return non-zero if not a structural or whitespace char
// zero otherwise
really_inline u32 is_not_structural_or_whitespace(u8 c) {
return structural_or_whitespace_negated[c];
}
never_inline bool shovel_machine(UNUSED const u8 * buf, UNUSED size_t len, UNUSED ParsedJson & pj) {
// fixup the mess made by the ape_machine
// as such it does a bunch of miscellaneous things on the tapes
u32 error_sump = 0;
// walk over each tape
for (u32 i = 0; i < MAX_DEPTH; i++) {
u32 start_loc = i*MAX_TAPE_ENTRIES;
for (u32 j = start_loc; j < tape_locs[i]; j+=2) {
count_tapes++;
switch (tape[j]>>24) {
case '{': case '[':
count_opens++;
// TODO: pivot our tapes
// point the enclosing structural char (}]) to the head marker ({[) and
// put the length of the sequence on the tape at the head marker
break;
case '"':
count_strings++;
// TODO: normalize strings
break;
case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
count_non_zeros++;
// TODO: read in a number
break;
case '0':
count_leading_zeros++;
// TODO: read in a number. Must be float so we can skip some stuff.
break;
case '-':
count_minus++;
// TODO: read in a number
break;
case 't': {
count_true++;
u32 offset = tape[j] & 0xffffff;
const u8 * loc = buf + offset;
error_sump |= memcmp(loc, "true", 4);
error_sump |= is_not_structural_or_whitespace(loc[4]);
break;
}
case 'f': {
count_false++;
u32 offset = tape[j] & 0xffffff;
const u8 * loc = buf + offset;
error_sump |= memcmp(loc, "false", 5);
error_sump |= is_not_structural_or_whitespace(loc[5]);
break;
}
case 'n': {
count_null++;
u32 offset = tape[j] & 0xffffff;
const u8 * loc = buf + offset;
error_sump |= memcmp(loc, "null", 4);
error_sump |= is_not_structural_or_whitespace(loc[4]);
break;
}
default:
break;
}
}
}
if (error_sump) {
cerr << "Ugh!\n";
return false;
}
return true;
}
// https://stackoverflow.com/questions/2616906/how-do-i-output-coloured-text-to-a-linux-terminal
namespace Color {
enum Code {
@ -623,8 +738,8 @@ int main(int argc, char * argv[]) {
#ifdef __linux__
LinuxEvents<PERF_TYPE_HARDWARE> cycles(PERF_COUNT_HW_CPU_CYCLES);
LinuxEvents<PERF_TYPE_HARDWARE> instructions(PERF_COUNT_HW_INSTRUCTIONS);
unsigned long cy1 = 0, cy2 = 0, cy3 = 0;
unsigned long cl1 = 0, cl2 = 0, cl3 = 0;
unsigned long cy1 = 0, cy2 = 0, cy3 = 0, cy4 = 0;
unsigned long cl1 = 0, cl2 = 0, cl3 = 0, cl4 = 0;
#endif
for (u32 i = 0; i < iterations; i++) {
auto start = std::chrono::steady_clock::now();
@ -647,6 +762,11 @@ int main(int argc, char * argv[]) {
#ifdef __linux__
cl3 += instructions.end(); cy3 += cycles.end();
//cy3 += cycles.end(); cl3 += instructions.end();
cycles.start(); instructions.start();
#endif
shovel_machine(p.first, p.second, pj);
#ifdef __linux__
cl4 += instructions.end(); cy4 += cycles.end();
#endif
auto end = std::chrono::steady_clock::now();
std::chrono::duration<double> secs = end - start;
@ -655,18 +775,31 @@ int main(int argc, char * argv[]) {
#ifdef __linux__
printf("number of bytes %ld number of structural chars %d ratio %.3f\n", p.second, pj.n_structural_indexes,
(double) pj.n_structural_indexes / p.second);
unsigned long total = cy1 + cy2 + cy3 ;
unsigned long total = cy1 + cy2 + cy3 + cy4;
printf("stage 1 instructions: %10lu cycles: %10lu (%.2f %%) ins/cycles: %.2f \n",
cl1, cy1, 100. * cy1 / total, (double) cl1 / cy1);
printf(" stage 1 runs at %.2f cycles per input byte.\n", (double) cy1 / (iterations * p.second));
printf("stage 2 instructions: %10lu cycles: %10lu (%.2f %%) ins/cycles: %.2f \n",
cl2, cy2, 100. * cy2 / total, (double) cl2 / cy2);
printf(" stage 2 runs at %.2f cycles per input byte and ", (double) cy2 / (iterations * p.second));
printf("%.2f cycles per structural character.\n", (double) cy2 / (iterations * pj.n_structural_indexes));
printf("stage 3 instructions: %10lu cycles: %10lu (%.2f %%) ins/cycles: %.2f \n",
cl3, cy3, 100. * cy3 / total, (double) cl3 / cy3);
printf(" stage 3 runs at %.2f cycles per input byte and ", (double) cy3 / (iterations * p.second));
printf("%.2f cycles per structural character.\n", (double) cy3 / (iterations * pj.n_structural_indexes));
printf("stage 4 instructions: %10lu cycles: %10lu (%.2f %%) ins/cycles: %.2f \n",
cl4, cy4, 100. * cy4 / total, (double) cl4 / cy4);
printf(" stage 4 runs at %.2f cycles per input byte and ", (double) cy4 / (iterations * p.second));
printf("%.2f cycles per structural character.\n", (double) cy4 / (iterations * pj.n_structural_indexes));
printf("There were %d elements on our tapes.\n", count_tapes);
printf("Opens %d strings %d non_zeros %d leading_zeros %d minus %d, true %d false %d null %d\n",
count_opens, count_strings, count_non_zeros, count_leading_zeros, count_minus, count_true, count_false, count_null);
printf(" all stages: %.2f cycles per input byte.\n", (double) total / (iterations * p.second));
#endif
// colorfuldisplay(pj, p.first);