add v1 + v2

This commit is contained in:
SimonFJ20 2023-03-22 22:50:23 +01:00
parent 7fb64179b8
commit 6fae6bb661
6 changed files with 208 additions and 18 deletions

View File

@ -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
View File

@ -0,0 +1 @@
++++++++[->-[->-[->-[-]<]<]<]>++++++++[<++++++++++>-]<[>+>+<<-]>-.>-----.>

9
src/fastbf.h Normal file
View 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

View File

@ -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
View 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
View 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);
}
}