add v1 + v2
This commit is contained in:
parent
7fb64179b8
commit
6fae6bb661
6
Makefile
6
Makefile
@ -1,8 +1,8 @@
|
||||
|
||||
CC = gcc
|
||||
|
||||
CFLAGS = -std=c17 -Wall -Wextra -Wpedantic -Wconversion -g -pg
|
||||
LFLAGS = -lm -g -pg
|
||||
CFLAGS = -std=c17 -Wall -Wextra -Wpedantic -Wconversion -g
|
||||
LFLAGS = -lm -g
|
||||
|
||||
TARGET= bf
|
||||
|
||||
@ -18,7 +18,7 @@ disasm: $(TARGET)
|
||||
|
||||
profile: $(TARGET)
|
||||
$(RM) perf.data profile.perf
|
||||
perf record -g -F max ./bf
|
||||
perf record --call-graph dwarf -F 10000 ./$(TARGET) < bench.bf
|
||||
perf script -F +pid > profile.perf
|
||||
|
||||
$(TARGET): $(OBJECT_FILES)
|
||||
|
1
bench.bf
Normal file
1
bench.bf
Normal file
@ -0,0 +1 @@
|
||||
++++++++[->-[->-[->-[-]<]<]<]>++++++++[<++++++++++>-]<[>+>+<<-]>-.>-----.>
|
9
src/fastbf.h
Normal file
9
src/fastbf.h
Normal file
@ -0,0 +1,9 @@
|
||||
#ifndef FASTBF_H
|
||||
#define FASTBF_H
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
void v1(const char* program, size_t length);
|
||||
void v2(const char* program, size_t length);
|
||||
|
||||
#endif
|
22
src/main.c
22
src/main.c
@ -1,20 +1,12 @@
|
||||
#include "fastbf.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
int takes_long(int b)
|
||||
{
|
||||
int a = 0;
|
||||
for (int i = 0; i < b; i++) {
|
||||
a = (a + 1) % 4;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
int get_a(void) { return takes_long(100000001); }
|
||||
int get_b(void) { return takes_long(200100001); }
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
puts("calculating...");
|
||||
int c = get_a() + get_b();
|
||||
printf("result = %d\n", c);
|
||||
char program[30000];
|
||||
fgets(program, 30000, stdin);
|
||||
v2(program, strlen(program));
|
||||
}
|
||||
|
63
src/v1.c
Normal file
63
src/v1.c
Normal file
@ -0,0 +1,63 @@
|
||||
#include "fastbf.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
simon@gamerarch:~/W/fastbf$ time ./bf < bench.bf
|
||||
OK
|
||||
real 0m0,680s
|
||||
user 0m0,676s
|
||||
sys 0m0,004s
|
||||
simon@gamerarch:~/W/fastbf$ time ./bf < bench.bf
|
||||
OK
|
||||
real 0m0,682s
|
||||
user 0m0,677s
|
||||
sys 0m0,003s
|
||||
simon@gamerarch:~/W/fastbf$ time ./bf < bench.bf
|
||||
OK
|
||||
real 0m0,679s
|
||||
user 0m0,679s
|
||||
sys 0m0,000s
|
||||
*/
|
||||
|
||||
void v1(const char* program, size_t length)
|
||||
{
|
||||
(void)length;
|
||||
uint8_t memory[30000];
|
||||
uint_fast16_t memory_index = 0;
|
||||
for (uint_fast16_t i = 0; i < length; i++) {
|
||||
char c = program[i];
|
||||
switch (c) {
|
||||
case '+':
|
||||
memory[memory_index]++;
|
||||
break;
|
||||
case '-':
|
||||
memory[memory_index]--;
|
||||
break;
|
||||
case '>':
|
||||
memory_index++;
|
||||
break;
|
||||
case '<':
|
||||
memory_index--;
|
||||
break;
|
||||
case '.':
|
||||
putc(memory[memory_index], stdout);
|
||||
break;
|
||||
case ',':
|
||||
memory[memory_index] = (uint8_t)getc(stdin);
|
||||
break;
|
||||
case ']':
|
||||
if (memory[memory_index]) {
|
||||
int depth = 1;
|
||||
while (program[i] != '[' || depth != 0) {
|
||||
i--;
|
||||
if (program[i] == ']')
|
||||
depth++;
|
||||
else if (program[i] == '[')
|
||||
depth--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
125
src/v2.c
Normal file
125
src/v2.c
Normal file
@ -0,0 +1,125 @@
|
||||
|
||||
#include "fastbf.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
simon@gamerarch:~/W/fastbf$ time ./bf < bench.bf
|
||||
OK
|
||||
real 0m0,563s
|
||||
user 0m0,558s
|
||||
sys 0m0,003s
|
||||
simon@gamerarch:~/W/fastbf$ time ./bf < bench.bf
|
||||
OK
|
||||
real 0m0,562s
|
||||
user 0m0,562s
|
||||
sys 0m0,000s
|
||||
simon@gamerarch:~/W/fastbf$ time ./bf < bench.bf
|
||||
OK
|
||||
real 0m0,569s
|
||||
user 0m0,569s
|
||||
sys 0m0,001s
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint_fast16_t begin;
|
||||
uint_fast16_t depth;
|
||||
} LoopEntry;
|
||||
|
||||
typedef struct {
|
||||
const char* program;
|
||||
size_t length;
|
||||
uint_fast16_t pc;
|
||||
uint_fast16_t sp;
|
||||
uint_fast16_t loop_depth;
|
||||
uint_fast16_t loops_length;
|
||||
uint_fast16_t loops_progress;
|
||||
LoopEntry loops[1000];
|
||||
uint8_t memory[30000];
|
||||
} Context;
|
||||
|
||||
void v2_incr(Context* ctx) { ctx->memory[ctx->sp]++; }
|
||||
void v2_decr(Context* ctx) { ctx->memory[ctx->sp]--; }
|
||||
void v2_right(Context* ctx) { ctx->sp++; }
|
||||
void v2_left(Context* ctx) { ctx->sp--; }
|
||||
void v2_put(Context* ctx) { putc(ctx->memory[ctx->sp], stdout); }
|
||||
void v2_get(Context* ctx) { ctx->memory[ctx->sp] = (uint8_t)getc(stdout); }
|
||||
|
||||
void v2_begin(Context* ctx)
|
||||
{
|
||||
if (ctx->loops_progress < ctx->pc) {
|
||||
ctx->loops_progress++;
|
||||
ctx->loops[ctx->loops_length] = (LoopEntry) {
|
||||
.begin = ctx->pc,
|
||||
.depth = ctx->loop_depth,
|
||||
};
|
||||
ctx->loops_length++;
|
||||
}
|
||||
ctx->loop_depth++;
|
||||
}
|
||||
|
||||
void v2_end(Context* ctx)
|
||||
{
|
||||
if (ctx->memory[ctx->sp]) {
|
||||
int entry_index = 0;
|
||||
for (int i = (int)ctx->loops_length - 1; i >= 0; i--)
|
||||
if (ctx->loops[i].depth == ctx->loop_depth)
|
||||
entry_index = i;
|
||||
ctx->pc = ctx->loops[entry_index].begin;
|
||||
} else {
|
||||
ctx->loop_depth--;
|
||||
}
|
||||
}
|
||||
|
||||
void v2_run_instruction(Context* ctx)
|
||||
{
|
||||
printf(
|
||||
"pc = %4ld, sp = %4ld, ins = %c\n",
|
||||
ctx->pc,
|
||||
ctx->sp,
|
||||
ctx->program[ctx->pc]
|
||||
);
|
||||
switch (ctx->program[ctx->pc]) {
|
||||
case '+':
|
||||
v2_incr(ctx);
|
||||
break;
|
||||
case '-':
|
||||
v2_decr(ctx);
|
||||
break;
|
||||
case '>':
|
||||
v2_right(ctx);
|
||||
break;
|
||||
case '<':
|
||||
v2_left(ctx);
|
||||
break;
|
||||
case '.':
|
||||
v2_put(ctx);
|
||||
break;
|
||||
case ',':
|
||||
v2_get(ctx);
|
||||
break;
|
||||
case '[':
|
||||
v2_begin(ctx);
|
||||
break;
|
||||
case ']':
|
||||
v2_end(ctx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void v2(const char* program, size_t length)
|
||||
{
|
||||
(void)length;
|
||||
Context ctx = {
|
||||
.program = program,
|
||||
.length = length,
|
||||
.pc = 0,
|
||||
.sp = 0,
|
||||
.loop_depth = 0,
|
||||
.loops_length = 0,
|
||||
.loops_progress = 0,
|
||||
};
|
||||
for (; ctx.pc < length; ctx.pc++) {
|
||||
v2_run_instruction(&ctx);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user