Use common ForkJoinPool for light calculations
This commit is contained in:
parent
425494e104
commit
f874b880ef
@ -75,7 +75,7 @@ fun main() {
|
||||
for (chunkX in 0 .. 100) {
|
||||
//for (chunkX in 0 .. 17) {
|
||||
// for (chunkY in 21 .. 21) {
|
||||
for (chunkY in 0 .. 24) {
|
||||
for (chunkY in 18 .. 24) {
|
||||
val data = db.read(byteArrayOf(1, 0, chunkX.toByte(), 0, chunkY.toByte()))
|
||||
val data2 = db.read(byteArrayOf(2, 0, chunkX.toByte(), 0, chunkY.toByte()))
|
||||
|
||||
|
@ -88,7 +88,7 @@ class StarboundClient : Closeable {
|
||||
val thread: Thread = Thread.currentThread()
|
||||
// client specific executor which will accept tasks which involve probable
|
||||
// callback to foreground executor to initialize thread-unsafe data
|
||||
// In above case multiple threads will introduce big congestion for resources
|
||||
// In above case too many threads will introduce big congestion for resources, stalling entire workload; wasting cpu resources
|
||||
val backgroundExecutor = ForkJoinPool(Runtime.getRuntime().availableProcessors().coerceAtMost(4))
|
||||
val foregroundExecutor = ManualExecutorService(thread)
|
||||
val capabilities: GLCapabilities
|
||||
|
@ -8,8 +8,13 @@ import ru.dbotthepony.kvector.arrays.Object2DArray
|
||||
import ru.dbotthepony.kvector.util.linearInterpolation
|
||||
import ru.dbotthepony.kvector.vector.RGBAColor
|
||||
import java.nio.ByteBuffer
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.ConcurrentLinkedQueue
|
||||
import java.util.concurrent.ForkJoinPool
|
||||
import java.util.concurrent.Future
|
||||
import java.util.concurrent.locks.LockSupport
|
||||
import java.util.function.Supplier
|
||||
import kotlin.math.roundToInt
|
||||
import kotlin.random.Random
|
||||
|
||||
@ -380,10 +385,9 @@ class LightCalculator(val parent: ICellAccess, val width: Int, val height: Int)
|
||||
// perform multithreaded calculation only when it makes sense
|
||||
if (multithreaded && pointLights.size > 1) {
|
||||
val thread = Thread.currentThread()
|
||||
|
||||
// calculate k-means clusters of point lights
|
||||
// to effectively utilize CPU cores
|
||||
val clusterCount = threads.size.coerceAtMost(pointLights.size)
|
||||
val clusterCount = ForkJoinPool.commonPool().parallelism.coerceAtMost(pointLights.size)
|
||||
val clusters = ArrayList<TaskCluster>(clusterCount)
|
||||
val startingPoints = IntArraySet()
|
||||
// val rand = Random(System.nanoTime())
|
||||
@ -394,7 +398,7 @@ class LightCalculator(val parent: ICellAccess, val width: Int, val height: Int)
|
||||
}
|
||||
|
||||
for (index in startingPoints.intIterator()) {
|
||||
clusters.add(TaskCluster(pointLights[index].x.toDouble(), pointLights[index].y.toDouble(), this, thread))
|
||||
clusters.add(TaskCluster(pointLights[index].x.toDouble(), pointLights[index].y.toDouble(), this))
|
||||
}
|
||||
|
||||
var converged = false
|
||||
@ -459,25 +463,14 @@ class LightCalculator(val parent: ICellAccess, val width: Int, val height: Int)
|
||||
}
|
||||
}
|
||||
|
||||
/*for ((i, cluster) in clusters.withIndex()) {
|
||||
val (r, g, b) = clusterColors[i]
|
||||
val tasks = ArrayList<Future<Grid>>()
|
||||
clusters.forEach { tasks.add(CompletableFuture.supplyAsync(it, ForkJoinPool.commonPool()).also { it.thenApply { LockSupport.unpark(thread); it } }) }
|
||||
|
||||
for (light in cluster.lights) {
|
||||
light.red = r
|
||||
light.green = g
|
||||
light.blue = b
|
||||
}
|
||||
}*/
|
||||
while (tasks.isNotEmpty()) {
|
||||
tasks.removeIf {
|
||||
if (it.isDone) {
|
||||
val grid = it.get()
|
||||
|
||||
tasks.addAll(clusters)
|
||||
wakeup()
|
||||
|
||||
while (clusters.isNotEmpty()) {
|
||||
clusters.removeIf {
|
||||
val grid = it.grid
|
||||
|
||||
// wait until thread local caches are refreshed
|
||||
if (grid != null) {
|
||||
if (targetMem != null) {
|
||||
for (x in grid.minX - 1 .. grid.maxX) {
|
||||
for (y in grid.minY - 1 .. grid.maxY) {
|
||||
@ -522,10 +515,10 @@ class LightCalculator(val parent: ICellAccess, val width: Int, val height: Int)
|
||||
}
|
||||
}
|
||||
|
||||
grid != null
|
||||
it.isDone
|
||||
}
|
||||
|
||||
LockSupport.parkNanos(500_000)
|
||||
LockSupport.parkNanos(500_000L)
|
||||
}
|
||||
} else {
|
||||
val grid = Grid()
|
||||
@ -589,8 +582,7 @@ class LightCalculator(val parent: ICellAccess, val width: Int, val height: Int)
|
||||
var x: Double,
|
||||
var y: Double,
|
||||
val parent: LightCalculator,
|
||||
val parentThread: Thread
|
||||
) {
|
||||
) : Supplier<Grid> {
|
||||
val lights = ArrayList<PointLight>()
|
||||
|
||||
fun updateCenter() {
|
||||
@ -608,13 +600,7 @@ class LightCalculator(val parent: ICellAccess, val width: Int, val height: Int)
|
||||
y /= lights.size
|
||||
}
|
||||
|
||||
@Volatile
|
||||
var grid: Grid? = null
|
||||
private set
|
||||
|
||||
fun execute() {
|
||||
if (grid != null) return
|
||||
|
||||
override fun get(): Grid {
|
||||
val grid = parent.Grid()
|
||||
|
||||
for (light in lights) {
|
||||
@ -635,46 +621,7 @@ class LightCalculator(val parent: ICellAccess, val width: Int, val height: Int)
|
||||
}
|
||||
|
||||
grid.calculateSpread()
|
||||
this.grid = grid
|
||||
LockSupport.unpark(parentThread)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private val tasks = ConcurrentLinkedQueue<TaskCluster>()
|
||||
private val threads = ArrayList<Thread>()
|
||||
|
||||
private val clusterColors = ArrayList<RGBAColor>()
|
||||
|
||||
private fun wakeup() {
|
||||
for (thread in threads) {
|
||||
LockSupport.unpark(thread)
|
||||
}
|
||||
}
|
||||
|
||||
private fun thread() {
|
||||
while (true) {
|
||||
val next = tasks.poll()
|
||||
|
||||
if (next == null) {
|
||||
LockSupport.park()
|
||||
continue
|
||||
}
|
||||
|
||||
next.execute()
|
||||
}
|
||||
}
|
||||
|
||||
init {
|
||||
for (i in 0 until Runtime.getRuntime().availableProcessors()) {
|
||||
Thread(::thread, "Starbound Lighting Thread $i").also { threads.add(it); it.isDaemon = true }.start()
|
||||
}
|
||||
|
||||
val rand = Random(System.nanoTime())
|
||||
|
||||
for (i in threads.indices) {
|
||||
clusterColors.add(RGBAColor(rand.nextFloat() * 0.5f + 0.5f, rand.nextFloat() * 0.5f + 0.5f, rand.nextFloat() * 0.5f + 0.5f))
|
||||
}
|
||||
return grid
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user