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 .. 100) {
|
||||||
//for (chunkX in 0 .. 17) {
|
//for (chunkX in 0 .. 17) {
|
||||||
// for (chunkY in 21 .. 21) {
|
// 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 data = db.read(byteArrayOf(1, 0, chunkX.toByte(), 0, chunkY.toByte()))
|
||||||
val data2 = db.read(byteArrayOf(2, 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()
|
val thread: Thread = Thread.currentThread()
|
||||||
// client specific executor which will accept tasks which involve probable
|
// client specific executor which will accept tasks which involve probable
|
||||||
// callback to foreground executor to initialize thread-unsafe data
|
// 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 backgroundExecutor = ForkJoinPool(Runtime.getRuntime().availableProcessors().coerceAtMost(4))
|
||||||
val foregroundExecutor = ManualExecutorService(thread)
|
val foregroundExecutor = ManualExecutorService(thread)
|
||||||
val capabilities: GLCapabilities
|
val capabilities: GLCapabilities
|
||||||
|
@ -8,8 +8,13 @@ import ru.dbotthepony.kvector.arrays.Object2DArray
|
|||||||
import ru.dbotthepony.kvector.util.linearInterpolation
|
import ru.dbotthepony.kvector.util.linearInterpolation
|
||||||
import ru.dbotthepony.kvector.vector.RGBAColor
|
import ru.dbotthepony.kvector.vector.RGBAColor
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
|
import java.util.concurrent.Callable
|
||||||
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.ConcurrentLinkedQueue
|
import java.util.concurrent.ConcurrentLinkedQueue
|
||||||
|
import java.util.concurrent.ForkJoinPool
|
||||||
|
import java.util.concurrent.Future
|
||||||
import java.util.concurrent.locks.LockSupport
|
import java.util.concurrent.locks.LockSupport
|
||||||
|
import java.util.function.Supplier
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
import kotlin.random.Random
|
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
|
// perform multithreaded calculation only when it makes sense
|
||||||
if (multithreaded && pointLights.size > 1) {
|
if (multithreaded && pointLights.size > 1) {
|
||||||
val thread = Thread.currentThread()
|
val thread = Thread.currentThread()
|
||||||
|
|
||||||
// calculate k-means clusters of point lights
|
// calculate k-means clusters of point lights
|
||||||
// to effectively utilize CPU cores
|
// 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 clusters = ArrayList<TaskCluster>(clusterCount)
|
||||||
val startingPoints = IntArraySet()
|
val startingPoints = IntArraySet()
|
||||||
// val rand = Random(System.nanoTime())
|
// 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()) {
|
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
|
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 tasks = ArrayList<Future<Grid>>()
|
||||||
val (r, g, b) = clusterColors[i]
|
clusters.forEach { tasks.add(CompletableFuture.supplyAsync(it, ForkJoinPool.commonPool()).also { it.thenApply { LockSupport.unpark(thread); it } }) }
|
||||||
|
|
||||||
for (light in cluster.lights) {
|
while (tasks.isNotEmpty()) {
|
||||||
light.red = r
|
tasks.removeIf {
|
||||||
light.green = g
|
if (it.isDone) {
|
||||||
light.blue = b
|
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) {
|
if (targetMem != null) {
|
||||||
for (x in grid.minX - 1 .. grid.maxX) {
|
for (x in grid.minX - 1 .. grid.maxX) {
|
||||||
for (y in grid.minY - 1 .. grid.maxY) {
|
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 {
|
} else {
|
||||||
val grid = Grid()
|
val grid = Grid()
|
||||||
@ -589,8 +582,7 @@ class LightCalculator(val parent: ICellAccess, val width: Int, val height: Int)
|
|||||||
var x: Double,
|
var x: Double,
|
||||||
var y: Double,
|
var y: Double,
|
||||||
val parent: LightCalculator,
|
val parent: LightCalculator,
|
||||||
val parentThread: Thread
|
) : Supplier<Grid> {
|
||||||
) {
|
|
||||||
val lights = ArrayList<PointLight>()
|
val lights = ArrayList<PointLight>()
|
||||||
|
|
||||||
fun updateCenter() {
|
fun updateCenter() {
|
||||||
@ -608,13 +600,7 @@ class LightCalculator(val parent: ICellAccess, val width: Int, val height: Int)
|
|||||||
y /= lights.size
|
y /= lights.size
|
||||||
}
|
}
|
||||||
|
|
||||||
@Volatile
|
override fun get(): Grid {
|
||||||
var grid: Grid? = null
|
|
||||||
private set
|
|
||||||
|
|
||||||
fun execute() {
|
|
||||||
if (grid != null) return
|
|
||||||
|
|
||||||
val grid = parent.Grid()
|
val grid = parent.Grid()
|
||||||
|
|
||||||
for (light in lights) {
|
for (light in lights) {
|
||||||
@ -635,46 +621,7 @@ class LightCalculator(val parent: ICellAccess, val width: Int, val height: Int)
|
|||||||
}
|
}
|
||||||
|
|
||||||
grid.calculateSpread()
|
grid.calculateSpread()
|
||||||
this.grid = grid
|
return 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))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user