vm_dispatch_compare.asm— comparador principal em MIPS Assembly para MARSvm_dispatch_compare.c— benchmark complementar em C paraperf stat
- Executa as duas arquiteturas no mesmo arquivo:
switch_dispatch: cadeia centralizada debeqthread_dispatch: jump table +jr
- Faz dois passes de demo:
- uma passada curta do switch
- uma passada curta do threading
- Faz o benchmark real com
ITERATIONS = 1000 - Imprime:
- enderecos de loops, handlers, pilha virtual e jump table
- contagem de bytecodes executados (
$s7) - contagem de branches de dispatch (
$s6) - resultado funcional final (
vm_mem[0]e topo da pilha)
- Abra
vm_dispatch_compare.asm - Use
Run -> Assemble - Confirme que
Delayed branchingesta desabilitado para a demonstracao ficar visualmente limpa
- Execute o programa uma vez com
Go - Observe no console:
Base da pilha virtualBase da memoria virtualSwitch dispatch loopBase da jump tablethread_table[0..5] slot- enderecos dos handlers
- Abra o painel
Data Segment - Localize
thread_tablee mostre que as entradas ficam lado a lado em memoria
- Reinicie (
Run -> Reset) - Coloque breakpoint em
switch_dispatch - Use
Step/F7 - Mostre o fluxo para um opcode simples:
PUSH: o PC chega emswitch_dispatch, passa pelo primeirobeqe entra no handlerADD: o PC passa por mais comparacoes antes de chegar ao handlerSTOREeHALT: o PC atravessa ainda mais comparacoes
- No painel
Registers, destaque:$s7: sobe 1 por bytecode interpretado$s6: sobe a cada comparacao do dispatch
- Reinicie (
Run -> Reset) - Coloque breakpoint em
thread_dispatch - Use
Step/F7 - Mostre o fluxo:
- fetch do opcode
- indexacao em
thread_table jrdiretamente para o handler
- Compare com o switch:
- o PC nao percorre uma cadeia de
beq - o dispatch distribuido volta para
thread_dispatchdepois de cada handler
- o PC nao percorre uma cadeia de
- Abra
Tools -> Instruction Counter - Resete o contador
- Coloque breakpoints em:
switch_benchmark_startswitch_benchmark_endthread_benchmark_startthread_benchmark_end
- Rode ate
switch_benchmark_start, zere o contador e continue ateswitch_benchmark_end - Anote o total de instrucoes MIPS
- Repita para
thread_benchmark_start->thread_benchmark_end
Leitura correta para a defesa:
- o contador do MARS mede instrucoes MIPS simuladas, nao branch miss real
- ele serve para mostrar o formato do fluxo de controle
- a tese de equivalencia pratica em CPU moderna deve ser sustentada com o binario C e
perf
Este ASM foi escrito para MIPS/MARS. Se voce portar a ideia para RISC-V/RARS:
- use o painel
Execution Statistics - compare principalmente:
instructions- instrucoes de branch/jump
- use o painel
Memorypara mostrar a jump table e a pilha virtual
O dado mais forte no RARS continua sendo estrutural: menos branches no threading. O argumento completo ainda depende de medir CPU real com perf.
Programa de teste por iteracao:
PUSH 10 / PUSH 20 / ADD / PUSH 5 / SUB / STORE 0 / LOAD 0 / HALT
Total de bytecodes por iteracao: 8
Com a ordem de comparacao PUSH, ADD, SUB, LOAD, STORE, HALT:
| Opcode | Comparacoes no switch |
|---|---|
| PUSH | 1 |
| ADD | 2 |
| SUB | 3 |
| LOAD | 4 |
| STORE | 5 |
| HALT | 6 |
Para a sequencia usada:
PUSH 10-> 1PUSH 20-> 1ADD-> 2PUSH 5-> 1SUB-> 3STORE-> 5LOAD-> 4HALT-> 6
Total por iteracao no switch: 23 branches de dispatch
Total por iteracao no threading: 8 branches de dispatch
| Metrica | Switch | Threading | Delta |
|---|---|---|---|
| Bytecodes executados | 8000 | 8000 | 0 |
| Branches de dispatch | 23000 | 8000 | 15000 |
Resultado final vm_mem[0] |
25 | 25 | 0 |
| Topo final da pilha | 25 | 25 | 0 |
- o threading claramente usa menos branches no ponto de dispatch
- isso prova diferenca estrutural
- isso nao prova, por si so, um ganho material de tempo em CPU moderna
- a sua tese entra aqui: com ISA minima, o ganho pratico tende a encolher; se o tempo final empata, o
switchvence por engenharia
Switch:
gcc -O3 -std=gnu11 -fno-jump-tables -DSWITCH vm_dispatch_compare.c -o vm_switchThreading:
gcc -O3 -std=gnu11 -DTHREADING vm_dispatch_compare.c -o vm_threadingSe quiser uma execucao curta para sanity check:
gcc -O3 -std=gnu11 -fno-jump-tables -DSWITCH -DITERATIONS=1000 vm_dispatch_compare.c -o vm_switch
gcc -O3 -std=gnu11 -DTHREADING -DITERATIONS=1000 vm_dispatch_compare.c -o vm_threadingperf stat -r 5 -e instructions,branches,branch-misses ./vm_switch
perf stat -r 5 -e instructions,branches,branch-misses ./vm_threadingbranches: tende a cair no threadingbranch-misses: em hardware moderno pode nao cair de forma dramaticainstructions: pode ficar proximo- se tempo total e miss rate ficarem proximos, sua conclusao fica defensavel:
- para ISA pequena, a vantagem do threading nao se converte em ganho relevante
- portanto
switche a opcao melhor de engenharia por portabilidade e simplicidade
No caso do binario SWITCH, inspecione rapidamente o assembly gerado para confirmar que o compilador nao transformou o switch em jump table:
objdump -d ./vm_switch | lessSe o compilador ainda gerar um lowering que descaracterize a comparacao, reduza a otimizacao para -O2 e reinspecione.