diff --git a/CMakeLists.txt b/CMakeLists.txt index 5856821..f766265 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -20,6 +20,8 @@ add_library(ink lib.c include/ink.h) # Removes several checks to improve performance in cases where ink is used as a bytecode # add_definitions(-DNOEXTRACHECKS) +add_definitions(-DINK_STEP_BATCH_COUNT=5) + add_executable(ink_exe main.c) target_link_libraries(ink_exe PUBLIC ink) target_include_directories(ink PUBLIC include) diff --git a/lib.c b/lib.c index c09c546..fb1421f 100644 --- a/lib.c +++ b/lib.c @@ -26,6 +26,14 @@ #define min(x, y) ((x) > (y) ? (y) : (x)) #define max(x, y) ((x) < (y) ? (y) : (x)) +#ifdef __GNUC__ +#define likely(x) __builtin_expect(!!(x), 1) +#define unlikely(x) __builtin_expect(!!(x), 0) +#else +#define likely(x) (!!(x)) +#define unlikely(x) (!!(x)) +#endif + struct label { int active; int dest; @@ -1071,35 +1079,41 @@ int ink_can_run(struct context* pContext) { } int ink_step_everyone(struct context* pContext) { - int out; - pContext->routine_current = -1; - for(;;) { - /* Increment to next runnable routine */ - do{ - ++(pContext->routine_current); - } while( - pContext->routine_current < pContext->routines_top - && pContext->routines[pContext->routine_current].panic != 0 - && pContext->routines[pContext->routine_current].parse_error.is_set - && pContext->routines[pContext->routine_current].runtime_error.is_set - ); - /* Exit condition */ - if(pContext->routine_current >= pContext->routines_top) break; - - /* Kill? */ - if(pContext->routines[pContext->routine_current].panic == INK_ROUTINE_SUCCESS) { - ink_kill_routine(pContext, pContext->routine_current); - } - - /* Step! */ - out = ink_step(pContext); - if(out == 0) { - pContext->routines[pContext->routine_current].panic = INK_ROUTINE_SUCCESS; - } else if(out < 0) { - pContext->routines[pContext->routine_current].panic = out; - } - } - return 0; + int idx; + int out; + pContext->routine_current = -1; + for(;;) { + top_label: + /* Increment to next runnable routine */ + do{ + ++(pContext->routine_current); + } while( + pContext->routine_current < pContext->routines_top + && pContext->routines[pContext->routine_current].panic != 0 + && pContext->routines[pContext->routine_current].parse_error.is_set + && pContext->routines[pContext->routine_current].runtime_error.is_set + ); + /* Exit condition */ + if(pContext->routine_current >= pContext->routines_top) break; + + /* Kill? */ + if(pContext->routines[pContext->routine_current].panic == INK_ROUTINE_SUCCESS) { + ink_kill_routine(pContext, pContext->routine_current); + } + + /* Step! */ + for(idx = 0; idx < INK_STEP_BATCH_COUNT; ++idx) { + out = ink_step(pContext); + if (unlikely(out == 0)) { + pContext->routines[pContext->routine_current].panic = INK_ROUTINE_SUCCESS; + goto top_label; + } else if (unlikely(out < 0)) { + pContext->routines[pContext->routine_current].panic = out; + goto top_label; + } + } + } + return 0; } int ink_new_type( diff --git a/main.c b/main.c index 76ae18a..3bc700d 100644 --- a/main.c +++ b/main.c @@ -4,8 +4,10 @@ int main(int argc, char** argv) { char read_buffer[2048]; + struct timespec start_time, end_time; clock_t begin, end; double time_spent; + double s_total = 0; struct context* ctx; char** end_argv; ctx = ink_make_default_context(); @@ -29,12 +31,16 @@ int main(int argc, char** argv) { } begin = clock(); + clock_gettime(CLOCK_MONOTONIC, &start_time); while(ink_can_run(ctx)) { ink_step_everyone(ctx); } + clock_gettime(CLOCK_MONOTONIC, &end_time); ink_gc(ctx); end = clock(); - time_spent = ctx->steps/((double)(end - begin) / CLOCKS_PER_SEC); - printf("\nExecuted in %u steps\nCollected %u times\nExecution freq: %uHz\n", ctx->steps, ctx->collections, (unsigned int)time_spent); + time_spent = ctx->steps/(double)((end - begin) / CLOCKS_PER_SEC); + s_total += (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec - start_time.tv_nsec) / 1.0e9; + s_total = ctx->steps / s_total; + printf("\nExecuted in %u steps\nCollected %u times\nExecution freq: %lfHz\n", ctx->steps, ctx->collections, s_total); return ctx->panic; } \ No newline at end of file diff --git a/test/test03.nk b/test/test03.nk index e69de29..97014a7 100644 --- a/test/test03.nk +++ b/test/test03.nk @@ -0,0 +1,19 @@ + +fn work do + 12 13 + 25 + 13 + 12 + 25 + 100 == + 12 13 + 25 + 13 + 12 + 25 + 100 == - + 12 13 + 25 + 13 + 12 + 25 + 100 == + 12 13 + 25 + 13 + 12 + 25 + 100 == - + + 12 13 + 25 + 13 + 12 + 25 + 100 == + 12 13 + 25 + 13 + 12 + 25 + 100 == - + 12 13 + 25 + 13 + 12 + 25 + 100 == + 12 13 + 25 + 13 + 12 + 25 + 100 == - + + + 12 13 + 25 + 13 + 12 + 25 + 100 == + 12 13 + 25 + 13 + 12 + 25 + 100 == - + 12 13 + 25 + 13 + 12 + 25 + 100 == + 12 13 + 25 + 13 + 12 + 25 + 100 == - + + 12 13 + 25 + 13 + 12 + 25 + 100 == + 12 13 + 25 + 13 + 12 + 25 + 100 == - + 12 13 + 25 + 13 + 12 + 25 + 100 == + 12 13 + 25 + 13 + 12 + 25 + 100 == - + + + 0 == +end \ No newline at end of file diff --git a/test/test06.nk b/test/test06.nk index ccd22b9..870387e 100644 --- a/test/test06.nk +++ b/test/test06.nk @@ -3,3 +3,22 @@ [ 72 101 108 108 111 32 87 111 114 108 100 10 ] stack.dump # This prints the array above +work work work work work +work work work work work +work work work work work +work work work work work +work work work work work +work work work work work +work work work work work +work work work work work +work work work work work +work work work work work +work work work work work +work work work work work +work work work work work +work work work work work +work work work work work +work work work work work +work work work work work +work work work work work +