Skip to content

Commit 61b43e9

Browse files
authored
Add first benchmarks - Python performance exceeded
1 parent b7579ba commit 61b43e9

File tree

3 files changed

+253
-2
lines changed

3 files changed

+253
-2
lines changed

benchmarks/nbody.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
# N body problem benchmark - Python vesion by Kevin Carson
2+
3+
import sys
4+
5+
def combinations(l):
6+
result = []
7+
for x in range(len(l) - 1):
8+
ls = l[x+1:]
9+
for y in ls:
10+
result.append((l[x],y))
11+
return result
12+
13+
PI = 3.14159265358979323
14+
SOLAR_MASS = 4 * PI * PI
15+
DAYS_PER_YEAR = 365.24
16+
17+
BODIES = {
18+
'sun': ([0.0, 0.0, 0.0], [0.0, 0.0, 0.0], SOLAR_MASS),
19+
20+
'jupiter': ([4.84143144246472090e+00,
21+
-1.16032004402742839e+00,
22+
-1.03622044471123109e-01],
23+
[1.66007664274403694e-03 * DAYS_PER_YEAR,
24+
7.69901118419740425e-03 * DAYS_PER_YEAR,
25+
-6.90460016972063023e-05 * DAYS_PER_YEAR],
26+
9.54791938424326609e-04 * SOLAR_MASS),
27+
28+
'saturn': ([8.34336671824457987e+00,
29+
4.12479856412430479e+00,
30+
-4.03523417114321381e-01],
31+
[-2.76742510726862411e-03 * DAYS_PER_YEAR,
32+
4.99852801234917238e-03 * DAYS_PER_YEAR,
33+
2.30417297573763929e-05 * DAYS_PER_YEAR],
34+
2.85885980666130812e-04 * SOLAR_MASS),
35+
36+
'uranus': ([1.28943695621391310e+01,
37+
-1.51111514016986312e+01,
38+
-2.23307578892655734e-01],
39+
[2.96460137564761618e-03 * DAYS_PER_YEAR,
40+
2.37847173959480950e-03 * DAYS_PER_YEAR,
41+
-2.96589568540237556e-05 * DAYS_PER_YEAR],
42+
4.36624404335156298e-05 * SOLAR_MASS),
43+
44+
'neptune': ([1.53796971148509165e+01,
45+
-2.59193146099879641e+01,
46+
1.79258772950371181e-01],
47+
[2.68067772490389322e-03 * DAYS_PER_YEAR,
48+
1.62824170038242295e-03 * DAYS_PER_YEAR,
49+
-9.51592254519715870e-05 * DAYS_PER_YEAR],
50+
5.15138902046611451e-05 * SOLAR_MASS) }
51+
52+
53+
SYSTEM = list(BODIES.values())
54+
PAIRS = combinations(SYSTEM)
55+
56+
57+
def advance(dt, n, bodies=SYSTEM, pairs=PAIRS):
58+
59+
for i in range(n):
60+
for (([x1, y1, z1], v1, m1),
61+
([x2, y2, z2], v2, m2)) in pairs:
62+
dx = x1 - x2
63+
dy = y1 - y2
64+
dz = z1 - z2
65+
mag = dt * ((dx * dx + dy * dy + dz * dz) ** (-1.5))
66+
b1m = m1 * mag
67+
b2m = m2 * mag
68+
v1[0] -= dx * b2m
69+
v1[1] -= dy * b2m
70+
v1[2] -= dz * b2m
71+
v2[0] += dx * b1m
72+
v2[1] += dy * b1m
73+
v2[2] += dz * b1m
74+
for (r, [vx, vy, vz], m) in bodies:
75+
r[0] += dt * vx
76+
r[1] += dt * vy
77+
r[2] += dt * vz
78+
79+
80+
def report_energy(bodies=SYSTEM, pairs=PAIRS, e=0.0):
81+
82+
for (((x1, y1, z1), v1, m1),
83+
((x2, y2, z2), v2, m2)) in pairs:
84+
dx = x1 - x2
85+
dy = y1 - y2
86+
dz = z1 - z2
87+
e -= (m1 * m2) / ((dx * dx + dy * dy + dz * dz) ** 0.5)
88+
for (r, [vx, vy, vz], m) in bodies:
89+
e += m * (vx * vx + vy * vy + vz * vz) / 2.
90+
print("%.9f" % e)
91+
92+
def offset_momentum(ref, bodies=SYSTEM, px=0.0, py=0.0, pz=0.0):
93+
94+
for (r, [vx, vy, vz], m) in bodies:
95+
px -= vx * m
96+
py -= vy * m
97+
pz -= vz * m
98+
(r, v, m) = ref
99+
v[0] = px / m
100+
v[1] = py / m
101+
v[2] = pz / m
102+
103+
def main(n, ref='sun'):
104+
offset_momentum(BODIES[ref])
105+
report_energy()
106+
advance(0.01, n)
107+
report_energy()
108+
109+
if __name__ == '__main__':
110+
main(int(sys.argv[1]))

benchmarks/nbody.um

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
// N body problem benchmark - Umka version
2+
3+
import "../import/std.um"
4+
5+
type Body = struct {
6+
x, y, z, vx, vy, vz, mass: real
7+
}
8+
9+
const (
10+
pi = 3.14159265358979323846
11+
solarMass = 4 * pi * pi
12+
daysPerYear = 365.24
13+
)
14+
15+
fn offsetMomentum(b: ^Body, px, py, pz: real) {
16+
b.vx = -px / solarMass
17+
b.vy = -py / solarMass
18+
b.vz = -pz / solarMass
19+
}
20+
21+
type System = []^Body
22+
23+
fn NewSystem(body: ^[]Body, len: int, sys: ^System) {
24+
for i := 0; i < len; i++ {
25+
sys[i] = &body[i]
26+
}
27+
var px, py, pz: real
28+
for i := 0; i < len; i++ {
29+
body := sys[i]
30+
px += body.vx * body.mass
31+
py += body.vy * body.mass
32+
pz += body.vz * body.mass
33+
}
34+
offsetMomentum(sys[0], px, py, pz)
35+
}
36+
37+
fn energy(sys: ^System, len: int): real {
38+
var e: real
39+
for i := 0; i < len; i++ {
40+
body := sys[i]
41+
e += 0.5 * body.mass * (body.vx*body.vx + body.vy*body.vy + body.vz*body.vz)
42+
for j := i + 1; j < len; j++ {
43+
body2 := sys[j]
44+
dx := body.x - body2.x
45+
dy := body.y - body2.y
46+
dz := body.z - body2.z
47+
distance := sqrt(dx*dx + dy*dy + dz*dz)
48+
e -= (body.mass * body2.mass) / distance
49+
}
50+
}
51+
return e
52+
}
53+
54+
fn advance(sys: ^System, len: int, dt: real) {
55+
for i := 0; i < len; i++ {
56+
body := sys[i]
57+
for j := i + 1; j < len; j++ {
58+
body2 := sys[j]
59+
dx := body.x - body2.x
60+
dy := body.y - body2.y
61+
dz := body.z - body2.z
62+
63+
dSquared := dx*dx + dy*dy + dz*dz
64+
distance := sqrt(dSquared)
65+
mag := dt / (dSquared * distance)
66+
67+
body.vx -= dx * body2.mass * mag
68+
body.vy -= dy * body2.mass * mag
69+
body.vz -= dz * body2.mass * mag
70+
71+
body2.vx += dx * body.mass * mag
72+
body2.vy += dy * body.mass * mag
73+
body2.vz += dz * body.mass * mag
74+
}
75+
}
76+
77+
for i := 0; i < len; i++ {
78+
body := sys[i]
79+
body.x += dt * body.vx
80+
body.y += dt * body.vy
81+
body.z += dt * body.vz
82+
}
83+
}
84+
85+
jupiter := Body{
86+
x: 4.84143144246472090e+00,
87+
y: -1.16032004402742839e+00,
88+
z: -1.03622044471123109e-01,
89+
vx: 1.66007664274403694e-03 * daysPerYear,
90+
vy: 7.69901118419740425e-03 * daysPerYear,
91+
vz: -6.90460016972063023e-05 * daysPerYear,
92+
mass: 9.54791938424326609e-04 * solarMass}
93+
94+
saturn := Body{
95+
x: 8.34336671824457987e+00,
96+
y: 4.12479856412430479e+00,
97+
z: -4.03523417114321381e-01,
98+
vx: -2.76742510726862411e-03 * daysPerYear,
99+
vy: 4.99852801234917238e-03 * daysPerYear,
100+
vz: 2.30417297573763929e-05 * daysPerYear,
101+
mass: 2.85885980666130812e-04 * solarMass}
102+
103+
uranus := Body{
104+
x: 1.28943695621391310e+01,
105+
y: -1.51111514016986312e+01,
106+
z: -2.23307578892655734e-01,
107+
vx: 2.96460137564761618e-03 * daysPerYear,
108+
vy: 2.37847173959480950e-03 * daysPerYear,
109+
vz: -2.96589568540237556e-05 * daysPerYear,
110+
mass: 4.36624404335156298e-05 * solarMass}
111+
112+
neptune := Body{
113+
x: 1.53796971148509165e+01,
114+
y: -2.59193146099879641e+01,
115+
z: 1.79258772950371181e-01,
116+
vx: 2.68067772490389322e-03 * daysPerYear,
117+
vy: 1.62824170038242295e-03 * daysPerYear,
118+
vz: -9.51592254519715870e-05 * daysPerYear,
119+
mass: 5.15138902046611451e-05 * solarMass}
120+
121+
sun := Body{
122+
x: 0, y: 0, z: 0, vx: 0, vy: 0, vz: 0,
123+
mass: solarMass}
124+
125+
126+
fn main() {
127+
if std.argc() == 3 {
128+
iter := std.atoi(std.argv(2))
129+
130+
const num = 5
131+
bodies := [num]Body{sun, jupiter, saturn, uranus, neptune}
132+
var system: [num]^Body
133+
NewSystem(&bodies, num, &system)
134+
printf("{.9f}\n", energy(&system, num))
135+
for i := 0; i < iter; i++ {
136+
advance(&system, num, 0.01)
137+
}
138+
printf("{.9f}\n", energy(&system, num))
139+
}
140+
}
141+

src/umka_vm.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1072,7 +1072,7 @@ int vmAsm(int ip, Instruction *instr, char *buf)
10721072
else if (instr->typeKind == TYPE_PTR)
10731073
chars += sprintf(buf + chars, " %p", instr->operand.ptrVal);
10741074
else
1075-
chars += sprintf(buf + chars, " %lld", instr->operand.intVal);
1075+
chars += sprintf(buf + chars, " %lld", (long long int)instr->operand.intVal);
10761076
break;
10771077
}
10781078
case OP_PUSH_LOCAL_PTR:
@@ -1090,7 +1090,7 @@ int vmAsm(int ip, Instruction *instr, char *buf)
10901090
case OP_GOTO_IF:
10911091
case OP_CALL:
10921092
case OP_RETURN:
1093-
case OP_ENTER_FRAME: chars += sprintf(buf + chars, " %lld", instr->operand.intVal); break;
1093+
case OP_ENTER_FRAME: chars += sprintf(buf + chars, " %lld", (long long int)instr->operand.intVal); break;
10941094
case OP_CALL_EXTERN: chars += sprintf(buf + chars, " %p", instr->operand.ptrVal); break;
10951095
case OP_CALL_BUILTIN: chars += sprintf(buf + chars, " %s", builtinSpelling[instr->operand.builtinVal]); break;
10961096

0 commit comments

Comments
 (0)