optimize arithmetics
This commit is contained in:
1 parent
161f3f74e2
commit
d8454a11fc
21 files changed
+913
-208
No files matched your search
+21
-21
@@ -1,18 +1,18 @@
|
||||
import lyng.time
|
||||
|
||||
val WORK_SIZE = 200
|
||||
val TASK_COUNT = 10
|
||||
val WORK_SIZE = 500
|
||||
val THREADS = 1
|
||||
|
||||
fn piSpigot(iThread: Int, n: Int) {
|
||||
var pi = []
|
||||
var piIter = 0
|
||||
var pi = List.fill(n) { 0 }
|
||||
val boxes = n * 10 / 3
|
||||
var reminders = List.fill(boxes) { 2 }
|
||||
var heldDigits = 0
|
||||
for (i in 0..n) {
|
||||
for (i in 0..<n) {
|
||||
var carriedOver = 0
|
||||
var sum = 0
|
||||
for (k in 1..boxes) {
|
||||
val j = boxes - k
|
||||
for (j in (boxes - 1) downTo 0) {
|
||||
val denom = j * 2 + 1
|
||||
reminders[j] *= 10
|
||||
sum = reminders[j] + carriedOver
|
||||
@@ -39,29 +39,29 @@ fn piSpigot(iThread: Int, n: Int) {
|
||||
} else {
|
||||
heldDigits = 1
|
||||
}
|
||||
pi.add(q)
|
||||
pi[piIter] = q
|
||||
++piIter
|
||||
}
|
||||
|
||||
var s = ""
|
||||
var res = ""
|
||||
for (i in (n - 8)..<n) {
|
||||
s += pi[i]
|
||||
res += pi[i]
|
||||
}
|
||||
|
||||
println(iThread, " - done: ", s)
|
||||
println(iThread.toString() + ": " + res)
|
||||
res
|
||||
}
|
||||
|
||||
var counter = 0
|
||||
for( r in 0..100 ) {
|
||||
val t0 = Instant()
|
||||
|
||||
val t0 = Instant()
|
||||
(1..TASK_COUNT).map { n ->
|
||||
val counterState = counter
|
||||
val t = launch {
|
||||
piSpigot(counterState, WORK_SIZE)
|
||||
println("piBench (lyng): THREADS = " + THREADS + ", WORK_SIZE = " + WORK_SIZE)
|
||||
for (i in 0..<THREADS) {
|
||||
piSpigot(i, WORK_SIZE)
|
||||
}
|
||||
++counter
|
||||
t
|
||||
}.forEach { (it as Deferred).await() }
|
||||
|
||||
val dt = Instant() - t0
|
||||
val dt = Instant() - t0
|
||||
|
||||
println("all done, dt = ", dt)
|
||||
println("all done, dt = ", dt)
|
||||
delay(800)
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
# Copyright 2026 Sergey S. Chernov real.sergeych@gmail.com
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import time
|
||||
from multiprocessing import Process
|
||||
|
||||
def piSpigot(iThread, nx):
|
||||
piIter = 0
|
||||
pi = [None] * nx
|
||||
boxes = nx * 10 // 3
|
||||
reminders = [None]*boxes
|
||||
i = 0
|
||||
while i < boxes:
|
||||
reminders[i] = 2
|
||||
i += 1
|
||||
heldDigits = 0
|
||||
i = 0
|
||||
while i < nx:
|
||||
carriedOver = 0
|
||||
sum = 0
|
||||
j = boxes - 1
|
||||
while j >= 0:
|
||||
reminders[j] *= 10
|
||||
sum = reminders[j] + carriedOver
|
||||
quotient = sum // (j * 2 + 1)
|
||||
reminders[j] = sum % (j * 2 + 1)
|
||||
carriedOver = quotient * j
|
||||
j -= 1
|
||||
reminders[0] = sum % 10
|
||||
q = sum // 10
|
||||
if q == 9:
|
||||
heldDigits += 1
|
||||
elif q == 10:
|
||||
q = 0
|
||||
k = 1
|
||||
while k <= heldDigits:
|
||||
replaced = pi[i - k]
|
||||
if replaced == 9:
|
||||
replaced = 0
|
||||
else:
|
||||
replaced += 1
|
||||
pi[i - k] = replaced
|
||||
k += 1
|
||||
heldDigits = 1
|
||||
else:
|
||||
heldDigits = 1
|
||||
pi[piIter] = q
|
||||
piIter += 1
|
||||
i += 1
|
||||
res = ""
|
||||
for i in range(len(pi)-8, len(pi), 1):
|
||||
res += str(pi[i])
|
||||
print(str(iThread) + ": " + res)
|
||||
|
||||
def createProcesses():
|
||||
THREADS = 1
|
||||
WORK_SIZE = 500
|
||||
print("piBench (python3): THREADS = " + str(THREADS) + ", WORK_SIZE = " + str(WORK_SIZE))
|
||||
pa = []
|
||||
for i in range(THREADS):
|
||||
p = Process(target=piSpigot, args=(i, WORK_SIZE))
|
||||
p.start()
|
||||
pa.append(p)
|
||||
for p in pa:
|
||||
p.join()
|
||||
|
||||
if __name__ == "__main__":
|
||||
t1 = time.time()
|
||||
createProcesses()
|
||||
dt = time.time() - t1
|
||||
print("total time: %i ms" % (dt*1000))
|
||||
@@ -1,49 +0,0 @@
|
||||
fn piSpigot(n) {
|
||||
var pi = []
|
||||
val boxes = n * 10 / 3
|
||||
var reminders = []
|
||||
for (i in 0..<boxes) {
|
||||
reminders.add(2)
|
||||
}
|
||||
var heldDigits = 0
|
||||
for (i in 0..n) {
|
||||
var carriedOver = 0
|
||||
var sum = 0
|
||||
for (k in 1..boxes) {
|
||||
val j = boxes - k
|
||||
val denom = j * 2 + 1
|
||||
reminders[j] *= 10
|
||||
sum = reminders[j] + carriedOver
|
||||
// Keep this integer-only. Real coercion here is much slower in the hot loop.
|
||||
val quotient = sum / denom
|
||||
reminders[j] = sum % denom
|
||||
carriedOver = quotient * j
|
||||
}
|
||||
reminders[0] = sum % 10
|
||||
var q = sum / 10
|
||||
if (q == 9) {
|
||||
++heldDigits
|
||||
} else if (q == 10) {
|
||||
q = 0
|
||||
for (k in 1..heldDigits) {
|
||||
var replaced = pi[i - k]
|
||||
if (replaced == 9) {
|
||||
replaced = 0
|
||||
} else {
|
||||
++replaced
|
||||
}
|
||||
pi[i - k] = replaced
|
||||
}
|
||||
heldDigits = 1
|
||||
} else {
|
||||
heldDigits = 1
|
||||
}
|
||||
pi.add(q)
|
||||
}
|
||||
|
||||
var suffix = ""
|
||||
for (i in (n - 8)..<n) {
|
||||
suffix += pi[i]
|
||||
}
|
||||
suffix
|
||||
}
|
||||
Reference in new issue
Block a user