Skip to content

Instantly share code, notes, and snippets.

@izmailoff
Last active December 19, 2016 15:48
Show Gist options
  • Save izmailoff/4aaa085a6240be167cfad511f6036d1e to your computer and use it in GitHub Desktop.
Save izmailoff/4aaa085a6240be167cfad511f6036d1e to your computer and use it in GitHub Desktop.
Estimate number of cores/threads your system can scale to aka cpu count
#!/bin/sh
exec scala -Dscala.concurrent.context.minThreads=16 -Dscala.concurrent.context.maxThreads=64 "$0" "$@"
!#
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.duration._
import java.util.concurrent.Executors
import scala.concurrent._
def time[R](block: => R): Long = {
val t0 = System.nanoTime()
val result = block
val t1 = System.nanoTime()
t1 - t0
}
def slowFunction = {
var i = 0L
while(i < Long.MaxValue / 1024 / 1024 / 1024) {
i += 1
//math.sqrt(i)
}
}
val maxCpuCount = 64
val errorMargin = 1.1
val warmupTimes = 10
//implicit val ec = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(maxCpuCount))
//implicit val ec = ExecutionContext.fromExecutorService(Executors.newSingleThreadExecutor)
def estimate_cpu_count(concurrencyLevel: Int = 1, firstTimingNanos: Long = 0): Int = {
val elapsed = time(Await.result(Future.sequence(List.fill(concurrencyLevel)(Future{slowFunction})),Duration.Inf))
val expected = (if(firstTimingNanos == 0) elapsed else firstTimingNanos)
val maxExpected = (expected * errorMargin).toLong
println(s"threads: $concurrencyLevel, (elapsed)$elapsed >? ${maxExpected}(max expected for this level)," +
s" elapsed/max: ${elapsed*100/maxExpected}%")
if(elapsed > maxExpected)
concurrencyLevel
else
estimate_cpu_count(concurrencyLevel + 1, expected)
}
def warmup() = (1 to warmupTimes).foreach(_ => slowFunction)
println(s"Warmup started, running $warmupTimes times before the actual test...")
warmup()
println("Warmup finished.")
println("Estimating CPU count...")
val estimatedCores = estimate_cpu_count()
val runtimeCores = Runtime.getRuntime.availableProcessors
println(s"Estimated cores: $estimatedCores, runtime cores: $runtimeCores")
@izmailoff
Copy link
Author

another machine (both i7 but different gen):

$ ./estimate_cpu_count_scala.sh 
Warmup started, running 10 times before the actual test...
Warmup finished.
Estimating CPU count...
threads: 1, (elapsed)2605980421 >? 2866578463(max expected for this level), elapsed/max:  90%
threads: 2, (elapsed)2549883180 >? 2866578463(max expected for this level), elapsed/max:  88%
threads: 3, (elapsed)2623480059 >? 2866578463(max expected for this level), elapsed/max:  91%
threads: 4, (elapsed)4214595473 >? 2866578463(max expected for this level), elapsed/max:  147%
Estimated cores: 4, runtime cores: 8

@izmailoff
Copy link
Author

hyperthreading is enabled, 1 CPU, 4 cores, 8 threads, i7 various generations

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment