Skip to content

Commit d15f7f7

Browse files
authored
perf(cek): cache 1 + 3 arg costs (#281)
Signed-off-by: Chris Gianelloni <wolf31o2@blinklabs.io>
1 parent 3164427 commit d15f7f7

2 files changed

Lines changed: 127 additions & 20 deletions

File tree

cek/machine.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,9 @@ type Machine[T syn.Eval] struct {
6868
builtins *Builtins[T]
6969
builtinValues *[builtin.TotalBuiltinCount]*Builtin[T]
7070
builtinNoArgValues *[builtin.TotalBuiltinCount][3]*Builtin[T]
71+
oneArgCosts [builtin.TotalBuiltinCount]oneArgCost
7172
twoArgCosts [builtin.TotalBuiltinCount]twoArgCost
73+
threeArgCosts [builtin.TotalBuiltinCount]threeArgCost
7274
available *[builtin.TotalBuiltinCount]bool
7375
slippage uint32
7476
version lang.LanguageVersion
@@ -679,7 +681,9 @@ func NewMachine[T syn.Eval](
679681
builtins: chooseBuiltins[T](version, evalContext.ProtoMajor),
680682
builtinValues: getSharedBuiltinValues[T](),
681683
builtinNoArgValues: getSharedBuiltinNoArgValues[T](),
684+
oneArgCosts: newOneArgCostCache(evalContext.CostModel.builtinCosts),
682685
twoArgCosts: newTwoArgCostCache(evalContext.CostModel.builtinCosts),
686+
threeArgCosts: newThreeArgCostCache(evalContext.CostModel.builtinCosts),
683687
available: chooseAvailableBuiltins(version, evalContext.ProtoMajor),
684688
slippage: slippage,
685689
version: version,

cek/runtime.go

Lines changed: 123 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -237,6 +237,36 @@ func (m *Machine[T]) evalBuiltinAppWithArg(
237237
return m.evalBuiltinAppReady(fn, forces, argCount, &finalArgs)
238238
}
239239

240+
type oneArgCost struct {
241+
mem OneArgument
242+
cpu OneArgument
243+
constant bool
244+
}
245+
246+
func newOneArgCostCache(
247+
costs BuiltinCosts,
248+
) [builtin.TotalBuiltinCount]oneArgCost {
249+
var ret [builtin.TotalBuiltinCount]oneArgCost
250+
for i, model := range costs {
251+
if model == nil {
252+
continue
253+
}
254+
255+
mem, memOK := model.mem.(OneArgument)
256+
cpu, cpuOK := model.cpu.(OneArgument)
257+
if !memOK || !cpuOK {
258+
continue
259+
}
260+
261+
ret[i] = oneArgCost{
262+
mem: mem,
263+
cpu: cpu,
264+
constant: mem.HasConstants()[0] && cpu.HasConstants()[0],
265+
}
266+
}
267+
return ret
268+
}
269+
240270
type twoArgCost struct {
241271
mem TwoArgument
242272
cpu TwoArgument
@@ -275,6 +305,48 @@ func newTwoArgCostCache(
275305
return ret
276306
}
277307

308+
type threeArgCost struct {
309+
mem ThreeArgument
310+
cpu ThreeArgument
311+
memConstX bool
312+
memConstY bool
313+
memConstZ bool
314+
cpuConstX bool
315+
cpuConstY bool
316+
cpuConstZ bool
317+
}
318+
319+
func newThreeArgCostCache(
320+
costs BuiltinCosts,
321+
) [builtin.TotalBuiltinCount]threeArgCost {
322+
var ret [builtin.TotalBuiltinCount]threeArgCost
323+
for i, model := range costs {
324+
if model == nil {
325+
continue
326+
}
327+
328+
mem, memOK := model.mem.(ThreeArgument)
329+
cpu, cpuOK := model.cpu.(ThreeArgument)
330+
if !memOK || !cpuOK {
331+
continue
332+
}
333+
334+
memConstants := mem.HasConstants()
335+
cpuConstants := cpu.HasConstants()
336+
ret[i] = threeArgCost{
337+
mem: mem,
338+
cpu: cpu,
339+
memConstX: memConstants[0],
340+
memConstY: memConstants[1],
341+
memConstZ: memConstants[2],
342+
cpuConstX: cpuConstants[0],
343+
cpuConstY: cpuConstants[1],
344+
cpuConstZ: cpuConstants[2],
345+
}
346+
}
347+
return ret
348+
}
349+
278350
// plutusVersionName returns a human-readable name for the Plutus version
279351
func plutusVersionName(v builtin.PlutusVersion) string {
280352
switch v {
@@ -294,18 +366,26 @@ func plutusVersionName(v builtin.PlutusVersion) string {
294366
}
295367

296368
func (m *Machine[T]) CostOne(b *builtin.DefaultFunction, x func() ExMem) error {
297-
model := m.costs.builtinCosts[*b]
298-
299-
mem := model.mem.(OneArgument)
300-
cpu := model.cpu.(OneArgument)
301-
302-
cf := CostingFunc[OneArgument]{
303-
mem: mem,
304-
cpu: cpu,
369+
model := &m.oneArgCosts[*b]
370+
mem := model.mem
371+
cpu := model.cpu
372+
if mem == nil || cpu == nil {
373+
fallbackModel := m.costs.builtinCosts[*b]
374+
mem = fallbackModel.mem.(OneArgument)
375+
cpu = fallbackModel.cpu.(OneArgument)
376+
model.mem = mem
377+
model.cpu = cpu
378+
model.constant = mem.HasConstants()[0] && cpu.HasConstants()[0]
305379
}
306380

307-
cost := CostSingle(cf, x)
308-
return m.spendBudget(cost)
381+
xMem := ExMem(0)
382+
if !model.constant {
383+
xMem = x()
384+
}
385+
return m.spendBudget(ExBudget{
386+
Mem: int64(mem.Cost(xMem)),
387+
Cpu: int64(cpu.Cost(xMem)),
388+
})
309389
}
310390

311391
func (m *Machine[T]) CostTwo(
@@ -365,18 +445,41 @@ func (m *Machine[T]) CostThree(
365445
b *builtin.DefaultFunction,
366446
x, y, z func() ExMem,
367447
) error {
368-
model := m.costs.builtinCosts[*b]
369-
370-
mem := model.mem.(ThreeArgument)
371-
cpu := model.cpu.(ThreeArgument)
372-
373-
cf := CostingFunc[ThreeArgument]{
374-
mem: mem,
375-
cpu: cpu,
448+
model := &m.threeArgCosts[*b]
449+
mem := model.mem
450+
cpu := model.cpu
451+
if mem == nil || cpu == nil {
452+
fallbackModel := m.costs.builtinCosts[*b]
453+
mem = fallbackModel.mem.(ThreeArgument)
454+
cpu = fallbackModel.cpu.(ThreeArgument)
455+
model.mem = mem
456+
model.cpu = cpu
457+
memConstants := mem.HasConstants()
458+
cpuConstants := cpu.HasConstants()
459+
model.memConstX = memConstants[0]
460+
model.memConstY = memConstants[1]
461+
model.memConstZ = memConstants[2]
462+
model.cpuConstX = cpuConstants[0]
463+
model.cpuConstY = cpuConstants[1]
464+
model.cpuConstZ = cpuConstants[2]
376465
}
377466

378-
cost := CostTriple(cf, x, y, z)
379-
return m.spendBudget(cost)
467+
xMem := ExMem(0)
468+
if !model.memConstX || !model.cpuConstX {
469+
xMem = x()
470+
}
471+
yMem := ExMem(0)
472+
if !model.memConstY || !model.cpuConstY {
473+
yMem = y()
474+
}
475+
zMem := ExMem(0)
476+
if !model.memConstZ || !model.cpuConstZ {
477+
zMem = z()
478+
}
479+
return m.spendBudget(ExBudget{
480+
Mem: int64(mem.CostThree(xMem, yMem, zMem)),
481+
Cpu: int64(cpu.CostThree(xMem, yMem, zMem)),
482+
})
380483
}
381484

382485
func (m *Machine[T]) CostThreeExMem(

0 commit comments

Comments
 (0)