diff options
| author | 2025-08-18 11:59:33 +0330 | |
|---|---|---|
| committer | 2025-08-18 11:59:33 +0330 | |
| commit | 450ced09c93ecb9c1c2c4c97fe2dde29439dac8f (patch) | |
| tree | 5fef31b7d27b0d21373956245f444fb2d7050c3d | |
| parent | i cant stop making cpus... here's a parallelized one (diff) | |
ppu isn't useful. i'll just go back to pu2
| -rw-r--r-- | ppu/code.p2p | 1 | ||||
| -rwxr-xr-x | ppu/ppu | bin | 0 -> 17464 bytes | |||
| -rw-r--r-- | ppu/ppu.c | 155 |
3 files changed, 137 insertions, 19 deletions
diff --git a/ppu/code.p2p b/ppu/code.p2p new file mode 100644 index 0000000..596ca02 --- /dev/null +++ b/ppu/code.p2p @@ -0,0 +1 @@ +@1048566 movi 1 1
\ No newline at end of file Binary files differ@@ -1,13 +1,16 @@ +// c89 doesnt support inline, so we get rid of it #define inline #include <ctype.h> +#include <limits.h> #include <omp.h> #include <stdio.h> #include <string.h> +#include <time.h> #pragma clang diagnostic ignored "-Wreturn-type" -typedef char* string; +typedef char *string; // opcodes! // 0: halt @@ -22,36 +25,150 @@ typedef char* string; // program counter is m[0] // Q is set to the previous A in memory +#define S 1 << 22 +m[ S ] = { 0 }, c, N, Q, E; + +// comment to disable cpu batch counter which guesses how many branches to run +#define __PPU_BATCH_COUNTER + +#ifdef __PPU_BATCH_COUNTER + #define BC (N = run_batch_counter()) +#else + #define BC ({}) +#endif + +#define MAX_BATCH_COUNT 16 + +run_batch_counter() { + int max_value = MAX_BATCH_COUNT; + int bcup_c = 0, i_count, j_count; + int bcupt[ MAX_BATCH_COUNT ]; + int *M = m; + // effects table + static const string effW = "001111111"; + static const string effR = "001010101"; + + for (i_count = 0; i_count < MAX_BATCH_COUNT; i_count++) { + if (i_count > max_value) break; + + int num = c + (i_count << 2); + int __N = M[ num++ ]; + int __O = M[ num++ ]; + int __A = M[ num++ ]; + int __B = M[ num++ ]; + + if (__N != 0) { + max_value = i_count + __N; + break; + } + if (__O == 0) { + max_value = i_count; + break; + } + if (__O >= 9) { + max_value = i_count - 1; + break; + } + + char w = effW[ __O ] - 48; + char r = effR[ __O ] - 48; + + for (j_count = 0; j_count < bcup_c; j_count++) { + int prev = bcupt[ j_count ]; + if ((prev == __A && w) || (prev == __B && r)) { + max_value = i_count - 1; + goto END; + } + } + + if (w) bcupt[ bcup_c++ ] = __A; + } + +END: + return max_value; +} + // error handling for unknown ops #define W 0 -// clang-format off #define J while -#define S 1<<20 #define H !K-- -m[S]={0},c,N,Q,E; -ppu(){E=1;_Pragma("omp parallel")J(E){_Pragma("omp single")N=m[m[0]],c=m[0],m[0]+=++N*4;int i;_Pragma("omp for")for(i=0;i<N;i++){int t=c+i*4,Y=m[t++],K=m[t++],A=m[t++],B=m[t++];H?E=0:H?:H?m[A]=m[B]:H?m[A]=B:H?m[A]+=m[B]:H?m[A]+=m[B]:H?m[A]-=m[B]?H:m[Q]?:(m[A]=m[B]):W;Q=A;}}} +ppu() { + E = 1; + J(E) { + _Pragma("omp single") N = m[ m[ 0 ] ], c = m[ 0 ], N ?: BC, m[ 0 ] += ++N * 4; + int i; + _Pragma("omp for") for (i = 0; i < N; i++) { + int t = c + i * 4, Y = m[ t++ ], K = m[ t++ ], A = m[ t++ ], B = m[ t++ ]; + H?E=0:H?:H?m[A]=m[B]:H?m[A]=B:H?m[A]+=m[B]:H?m[A]+=m[B]:H?m[A]-=m[B]?H:m[Q]?:(m[A]=m[B]):W; + Q = A; + } + } +} +// clang-format off #define X J(isspace(*I))I++ char*t="halt\0\0nop\0\0mov\0\2movi\0\2add\0\2addi\0\2sub\0\2subi\0\2moveq\0\2\1";*D,Z; char*pas(char*I){J(*I){X;if(*I==64)Z=strtol(++I,&I,10);X;char*O=t,F=0;J(*O!=1){int G=strlen(O),L=O[G+1],V=L,B=strncmp(I,O,G);F++,O+=G+2;if(B||!isspace(I[G]))continue;I+=G;*D++=Z,Z=0;*D++=F-1;J(V--){X;*D++=strtol(I,&I,10);}J(2-L++)*D++=0;goto N;}return I;N:;}return 0;} // clang-format on +string read_file(string path, size_t *out_size) { + FILE *f = fopen(path, "rb"); + string buf; + size_t size; + if (!f) return NULL; + fseek(f, 0, SEEK_END); + size = ftell(f); + fseek(f, 0, SEEK_SET); + buf = malloc(size + 1); + if (!buf) { + fclose(f); + return NULL; + } + if (fread(buf, 1, size, f) != size) { + free(buf); + fclose(f); + return NULL; + } + buf[ size ] = '\0'; + fclose(f); + if (out_size) *out_size = size; + return buf; +} + +unsigned long long rdtsc(void) { + unsigned hi, lo; + __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi)); + return ((unsigned long long) hi << 32) | lo; +} + main() { - D = &m[ 1 ]; - pas("@4 movi 10 2"); + D = &m[ 1000 ]; + m[ 0 ] = 1000; + size_t o_size; + string output = read_file("code.p2p", &o_size); + pas(output); + free(output); // int C; - // for (C = 0; C < 16; C++) printf("%i ", m[ C + 1 ]); - // fflush(stdout); - - int x[] = { 1, - 3, 3, 5, 1, - 0, 3, 5, 2, - 0, 3, 5, 3, - 0, 3, 5, 4, - 0, 0, 0, 0 }; - memcpy(m, x, sizeof(x)); - ppu(); - printf("result: %i\n", m[ 5 ]); + // for (C = 0; C < 16; C++) printf("%i ", m[ 1000 + C ]); + // putchar('\n'); + + // int x[] = { 1, 3, 3, 5, 1, 0, 3, 5, 2, 0, 3, 5, 3, 0, 3, 5, 4, 0, 0, 0, 0 }; + // memcpy(m, x, sizeof(x)); + + _Pragma("omp parallel") { + _Pragma("omp single") { + clock_t start = clock(); + ppu(); + clock_t end = clock(); + + double seconds = (double) (end - start) / CLOCKS_PER_SEC; + printf("time: %.6fs, insts: %i\n", seconds, m[ 0 ] / 4); + double insts_per_sec = ((double) m[ 0 ] / 4) / seconds; + printf("ran at %f million instructions/second\n", insts_per_sec / 1e6); + } + } + + printf("result: %i\n\n", m[ 1 ]); }
\ No newline at end of file |
