Skip to content

Commit 6e9e386

Browse files
authored
Merge pull request #502 from Gathros/monte_carlo_asm
Monte carlo in X86_64
2 parents b5bc757 + e48a90d commit 6e9e386

File tree

2 files changed

+92
-0
lines changed

2 files changed

+92
-0
lines changed
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
.intel_syntax noprefix
2+
3+
.section .rodata
4+
pi: .double 3.141592653589793
5+
one: .double 1.0
6+
four: .double 4.0
7+
hundred: .double 100.0
8+
rand_max: .long 4290772992
9+
.long 1105199103
10+
fabs_const: .long 4294967295
11+
.long 2147483647
12+
.long 0
13+
.long 0
14+
estimate_fmt: .string "The estaimate of pi is %lf\n"
15+
error_fmt: .string "Percentage error: %0.2f\n"
16+
17+
.section .text
18+
.global main
19+
.extern printf, srand, time, rand
20+
21+
# xmm0 - x
22+
# xmm1 - y
23+
# RET rax - bool
24+
in_circle:
25+
mulsd xmm0, xmm0 # Calculate x * x + y * y
26+
mulsd xmm1, xmm1
27+
addsd xmm0, xmm1
28+
movsd xmm1, one # Set circle radius to 1
29+
xor rax, rax
30+
comisd xmm1, xmm0 # Return bool xmm0 < xmm1
31+
seta al
32+
ret
33+
34+
# rdi - samples
35+
# RET xmm0 - estimate
36+
monte_carlo:
37+
pxor xmm2, xmm2 # Setting it to zero for loop
38+
cvtsi2sd xmm3, rdi # From int to double
39+
pxor xmm4, xmm4 # Setting to zero for counter
40+
monte_carlo_iter:
41+
comisd xmm2, xmm3 # Check if we went through all samples
42+
je monte_carlo_return
43+
call rand # Get random point in the first quartile
44+
cvtsi2sd xmm0, rax
45+
divsd xmm0, rand_max
46+
call rand
47+
cvtsi2sd xmm1, rax
48+
divsd xmm1, rand_max
49+
call in_circle # Check if its in the circle
50+
test rax, rax
51+
jz monte_carlo_false
52+
addsd xmm4, one # if so increment counter
53+
monte_carlo_false:
54+
addsd xmm2, one
55+
jmp monte_carlo_iter
56+
monte_carlo_return:
57+
mulsd xmm4, four # Return estimate
58+
divsd xmm4, xmm2
59+
movsd xmm0, xmm4
60+
ret
61+
62+
main:
63+
push rbp
64+
sub rsp, 16
65+
mov rdi, 0
66+
call time
67+
mov rdi, rax
68+
call srand
69+
mov rdi, 1000000
70+
call monte_carlo
71+
movsd QWORD PTR [rsp], xmm0 # Save estimate to stack
72+
mov rdi, OFFSET estimate_fmt # Print estimate
73+
mov rax, 1
74+
call printf
75+
movsd xmm0, QWORD PTR [rsp] # Get estimate from stack
76+
movsd xmm1, pi # Calculate fabs(M_PI - estimate)
77+
subsd xmm0, xmm1
78+
movq xmm1, fabs_const
79+
andpd xmm0, xmm1
80+
divsd xmm0, pi # Print percentage error on pi
81+
mulsd xmm0, hundred
82+
mov rdi, OFFSET error_fmt
83+
mov rax, 1
84+
call printf
85+
add rsp, 16
86+
pop rbp
87+
ret
88+

contents/monte_carlo_integration/monte_carlo_integration.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,8 @@ each point is tested to see whether it's in the circle or not:
8181
[import:2-4, lang:"lisp"](code/racket/monte_carlo.rkt)
8282
{% sample lang="scala" %}
8383
[import:3-3, lang:"scala"](code/scala/monte_carlo.scala)
84+
{% sample lang="asm-x64" %}
85+
[import:21-32, lang:"asm-x64"](code/asm-x64/monte_carlo.s)
8486
{% endmethod %}
8587

8688
If it's in the circle, we increase an internal count by one, and in the end,
@@ -161,6 +163,8 @@ Feel free to submit your version via pull request, and thanks for reading!
161163
[import, lang:"lisp"](code/racket/monte_carlo.rkt)
162164
{% sample lang="scala" %}
163165
[import, lang:"scala"](code/scala/monte_carlo.scala)
166+
{% sample lang="asm-x64" %}
167+
[import, lang:"asm-x64"](code/asm-x64/monte_carlo.s)
164168
{% endmethod %}
165169

166170

0 commit comments

Comments
 (0)