add a little readme, factor things properly
This commit is contained in:
parent
b8c9d55258
commit
335a9cc99a
37
Program.cs
37
Program.cs
|
|
@ -330,7 +330,23 @@ internal static class Parsing
|
|||
|
||||
public static EvaluationInstructions Parse(string filename)
|
||||
{
|
||||
var identifiers = new Dictionary<string, Operand>();
|
||||
// parse all identifiers first, so we know which are directly associated with constant values
|
||||
Dictionary<string, Operand> identifiers = ParseIdentifiers(filename);
|
||||
|
||||
// now parse instructions, correctly tagging operands that operate directly on constants
|
||||
List<Instruction> instructions = ParseInstructions(filename, identifiers);
|
||||
|
||||
// eliminate any constants from the tape, folding them into the instruction operands instead
|
||||
(int totalNumberOfInstructions, int numberOfRemovedInstructions) = EliminateConstants(instructions);
|
||||
Console.WriteLine($"Sharpero eliminated {numberOfRemovedInstructions} constants from tape, {(float)numberOfRemovedInstructions / totalNumberOfInstructions * 100.0f:0.0} % of total");
|
||||
|
||||
return new EvaluationInstructions(instructions.ToArray());
|
||||
}
|
||||
|
||||
private static Dictionary<string, Operand> ParseIdentifiers(string filename)
|
||||
{
|
||||
Dictionary<string, Operand> identifiers = [];
|
||||
|
||||
foreach (string line in File.ReadAllLines(filename))
|
||||
{
|
||||
if (line.StartsWith('#'))
|
||||
|
|
@ -358,7 +374,13 @@ internal static class Parsing
|
|||
}
|
||||
}
|
||||
|
||||
return identifiers;
|
||||
}
|
||||
|
||||
private static List<Instruction> ParseInstructions(string filename, Dictionary<string, Operand> identifiers)
|
||||
{
|
||||
List<Instruction> instructions = [];
|
||||
|
||||
foreach (string line in File.ReadAllLines(filename))
|
||||
{
|
||||
if (line.StartsWith('#'))
|
||||
|
|
@ -388,16 +410,17 @@ internal static class Parsing
|
|||
}
|
||||
}
|
||||
|
||||
bool shouldEliminateConstants = true;
|
||||
return instructions;
|
||||
}
|
||||
|
||||
if (shouldEliminateConstants)
|
||||
private static (int TotalInstructions, int NumberOfRemovedInstructions) EliminateConstants(List<Instruction> instructions)
|
||||
{
|
||||
// handle constant propagation, eliminating all constants from the instruction stream and merging them
|
||||
foreach (ref Instruction instruction in CollectionsMarshal.AsSpan(instructions))
|
||||
{
|
||||
switch (instruction.OpCode)
|
||||
{
|
||||
case (OpCode.Add or OpCode.Sub or OpCode.Mul) when instruction.A.IsConstant || instruction.B.IsConstant:
|
||||
case OpCode.Add or OpCode.Sub or OpCode.Mul when instruction.A.IsConstant || instruction.B.IsConstant:
|
||||
switch (instruction)
|
||||
{
|
||||
case { A: { IsConstant: true } a, B.IsConstant: false }:
|
||||
|
|
@ -455,13 +478,9 @@ internal static class Parsing
|
|||
}
|
||||
}
|
||||
|
||||
// eliminate all constants now :)
|
||||
int totalNumberOfInstructions = instructions.Count;
|
||||
int numberOfRemovedInstructions = instructions.RemoveAll(i => i.OpCode == OpCode.Const);
|
||||
Console.WriteLine($"Sharpero eliminated {numberOfRemovedInstructions} constants from tape, {(float)numberOfRemovedInstructions / totalNumberOfInstructions * 100.0f:0.0} % of total");
|
||||
}
|
||||
|
||||
return new EvaluationInstructions(instructions.ToArray());
|
||||
return (TotalInstructions: totalNumberOfInstructions, NumberOfRemovedInstructions: numberOfRemovedInstructions);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,20 @@
|
|||
Sharpero
|
||||
----------
|
||||
This is an implementation of an Interpreter/Compiler for the [Prospero](https://www.mattkeeter.com/projects/prospero/) challenge, implementing some basic optimizations including removing constants from the instruction tape, vectorization, parallelization but also optionally compiling the loop of the evaluator to [CIL](https://en.wikipedia.org/wiki/Common_Intermediate_Language) prior to invocation.
|
||||
|
||||
It doesn't perform any sophisticated interval-arithmetic based optimizations (... yet), it's essentially a brute-force approach.
|
||||
|
||||
This program is also an interactive visualizer of the rendering process, allowing you to see exactly how it's writing the image data out, and toggle vectorization, parallel execution, compilation on/off and observe the effects on runtime.
|
||||
|
||||
On my own machine (CPU: Ryzen 7 4800HS), the results tabulate roughly as follows.
|
||||
|
||||
# (Crude) Benchmark Results
|
||||
| Compilation | Parallelism | Vectorization | Evaluation Time | Compilation Time |
|
||||
|-------------|-------------|---------------|-----------------|------------------|
|
||||
| enabled | enabled | enabled | 0.2s | 0.2s |
|
||||
| enabled | enabled | disabled | 1.3s | 0.2s |
|
||||
| enabled | disabled | enabled | 1.7s | 0.2s |
|
||||
| enabled | disabled | disabled | 10s | 0.2s |
|
||||
| disabled | enabled | enabled | 0.7s | N/A |
|
||||
| disabled | enabled | disabled | 5.0s | N/A |
|
||||
| disabled | disabled | disabled | 48s | N/A |
|
||||
Loading…
Reference in New Issue