Thread safety for status updates, periodically minify
This commit is contained in:
@@ -48,7 +48,7 @@ func (def *Definition) Grow(statusChan chan<- Status) (*vm.Program, error) {
|
|||||||
for {
|
for {
|
||||||
status.Attempts++
|
status.Attempts++
|
||||||
|
|
||||||
Mutate(prog)
|
Mutate(def, prog)
|
||||||
|
|
||||||
score, err := def.score(prog)
|
score, err := def.score(prog)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -58,7 +58,7 @@ func (def *Definition) Grow(statusChan chan<- Status) (*vm.Program, error) {
|
|||||||
|
|
||||||
if score > status.BestScore {
|
if score > status.BestScore {
|
||||||
status.BestScore = score
|
status.BestScore = score
|
||||||
status.BestProgram = prog
|
status.BestProgram = prog.Copy()
|
||||||
|
|
||||||
if statusChan != nil {
|
if statusChan != nil {
|
||||||
statusChan <- status
|
statusChan <- status
|
||||||
@@ -73,6 +73,7 @@ func (def *Definition) Grow(statusChan chan<- Status) (*vm.Program, error) {
|
|||||||
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
status.BestProgram = prog.Copy()
|
||||||
|
|
||||||
if statusChan != nil {
|
if statusChan != nil {
|
||||||
statusChan <- status
|
statusChan <- status
|
||||||
@@ -142,6 +143,7 @@ func (def *Definition) minifyFunction(prog *vm.Program, f int) error {
|
|||||||
|
|
||||||
for i := 0; i < len(prog.Functions[f].Instructions); i++ {
|
for i := 0; i < len(prog.Functions[f].Instructions); i++ {
|
||||||
origInstructions := prog.Functions[f].Instructions
|
origInstructions := prog.Functions[f].Instructions
|
||||||
|
|
||||||
tmp := make([]*vm.Instruction, len(prog.Functions[f].Instructions))
|
tmp := make([]*vm.Instruction, len(prog.Functions[f].Instructions))
|
||||||
copy(tmp, prog.Functions[f].Instructions)
|
copy(tmp, prog.Functions[f].Instructions)
|
||||||
prog.Functions[f].Instructions = append(tmp[:i], tmp[i+1:]...)
|
prog.Functions[f].Instructions = append(tmp[:i], tmp[i+1:]...)
|
||||||
|
|||||||
@@ -8,7 +8,13 @@ import "github.com/firestuff/subcoding/vm"
|
|||||||
const instructionsPerFunctionMean = 15
|
const instructionsPerFunctionMean = 15
|
||||||
const instrucitonsPerFunctionStdDev = 10
|
const instrucitonsPerFunctionStdDev = 10
|
||||||
|
|
||||||
func Mutate(prog *vm.Program) {
|
const minifyPeriodMean = 10000
|
||||||
|
|
||||||
|
func Mutate(def *Definition, prog *vm.Program) {
|
||||||
|
if rand.Intn(minifyPeriodMean) == 0 {
|
||||||
|
def.minifyProgram(prog) // ignore error
|
||||||
|
}
|
||||||
|
|
||||||
target := int(rand.NormFloat64()*instrucitonsPerFunctionStdDev + instructionsPerFunctionMean)
|
target := int(rand.NormFloat64()*instrucitonsPerFunctionStdDev + instructionsPerFunctionMean)
|
||||||
|
|
||||||
if len(prog.Functions[0].Instructions) < target {
|
if len(prog.Functions[0].Instructions) < target {
|
||||||
|
|||||||
@@ -3,3 +3,13 @@ package vm
|
|||||||
type Function struct {
|
type Function struct {
|
||||||
Instructions []*Instruction
|
Instructions []*Instruction
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (fnc *Function) Copy() *Function {
|
||||||
|
ret := &Function{}
|
||||||
|
|
||||||
|
for _, instr := range fnc.Instructions {
|
||||||
|
ret.Instructions = append(ret.Instructions, instr.Copy())
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|||||||
@@ -7,3 +7,15 @@ type Instruction struct {
|
|||||||
|
|
||||||
opHandler opHandler `struc:"skip"`
|
opHandler opHandler `struc:"skip"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (instr *Instruction) Copy() *Instruction {
|
||||||
|
ret := &Instruction{
|
||||||
|
OpCode: instr.OpCode,
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, opr := range instr.Operands {
|
||||||
|
ret.Operands[i] = opr.Copy()
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|||||||
@@ -13,3 +13,14 @@ type Operand struct {
|
|||||||
Reserved [3]byte
|
Reserved [3]byte
|
||||||
Value uint64
|
Value uint64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (opr *Operand) Copy() *Operand {
|
||||||
|
if opr == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return &Operand{
|
||||||
|
Type: opr.Type,
|
||||||
|
Value: opr.Value,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -6,3 +6,17 @@ type Program struct {
|
|||||||
InstructionLimit uint64
|
InstructionLimit uint64
|
||||||
Functions []*Function
|
Functions []*Function
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (prog *Program) Copy() *Program {
|
||||||
|
ret := &Program{
|
||||||
|
GlobalMemorySize: prog.GlobalMemorySize,
|
||||||
|
FunctionMemorySize: prog.FunctionMemorySize,
|
||||||
|
InstructionLimit: prog.InstructionLimit,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, fnc := range prog.Functions {
|
||||||
|
ret.Functions = append(ret.Functions, fnc.Copy())
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user