mirror of
https://gitlab.bixilon.de/bixilon/minosoft.git
synced 2025-09-13 09:26:11 -04:00
improve thread pool (performance), improve culling performance
This commit is contained in:
parent
ec7ef10add
commit
7344fdda6c
@ -36,7 +36,7 @@ class ChunkSection(
|
||||
var light: IntArray, // packed (skyLight: 0xF0, blockLight: 0x0F)
|
||||
) {
|
||||
|
||||
constructor(registries: Registries) : this(RegistrySectionDataProvider<BlockState?>(registries.blockStateRegistry.unsafeCast(), checkSize = true), RegistrySectionDataProvider(registries.biomeRegistry, checkSize = false), SectionDataProvider(checkSize = true), IntArray(ProtocolDefinition.BLOCKS_PER_SECTION))
|
||||
constructor(registries: Registries) : this(RegistrySectionDataProvider<BlockState?>(registries.blockStateRegistry.unsafeCast(), checkSize = true), RegistrySectionDataProvider(registries.biomeRegistry, checkSize = false), SectionDataProvider(checkSize = false), IntArray(ProtocolDefinition.BLOCKS_PER_SECTION))
|
||||
|
||||
fun tick(connection: PlayConnection, chunkPosition: Vec2i, sectionHeight: Int) {
|
||||
if (blockEntities.isEmpty) {
|
||||
|
@ -18,7 +18,7 @@ import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
|
||||
class RegistrySectionDataProvider<T>(
|
||||
val registry: AbstractRegistry<T>,
|
||||
data: Array<Any?> = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION),
|
||||
data: Array<Any?>? = null,
|
||||
checkSize: Boolean = false,
|
||||
) : SectionDataProvider<T>(data, checkSize = checkSize) {
|
||||
|
||||
|
@ -13,15 +13,16 @@
|
||||
|
||||
package de.bixilon.minosoft.data.world.container
|
||||
|
||||
import de.bixilon.minosoft.gui.rendering.util.vec.vec3.Vec3iUtil.EMPTY
|
||||
import de.bixilon.minosoft.protocol.protocol.ProtocolDefinition
|
||||
import de.bixilon.minosoft.util.SemaphoreLock
|
||||
import glm_.vec3.Vec3i
|
||||
|
||||
open class SectionDataProvider<T>(
|
||||
data: Array<Any?> = arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION),
|
||||
data: Array<Any?>? = null,
|
||||
val checkSize: Boolean = false,
|
||||
) : Iterable<T> {
|
||||
protected var data = data
|
||||
protected var data = data ?: arrayOfNulls(ProtocolDefinition.BLOCKS_PER_SECTION)
|
||||
private set
|
||||
protected val lock = SemaphoreLock() // lock while reading (blocks writing)
|
||||
var count: Int = 0
|
||||
@ -34,7 +35,12 @@ open class SectionDataProvider<T>(
|
||||
private set
|
||||
|
||||
init {
|
||||
recalculate()
|
||||
if (data != null) {
|
||||
recalculate()
|
||||
} else {
|
||||
minPosition = Vec3i.EMPTY
|
||||
maxPosition = Vec3i.EMPTY
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
@ -55,9 +61,9 @@ open class SectionDataProvider<T>(
|
||||
return data[y shl 8 or (z shl 4) or x] as T
|
||||
}
|
||||
|
||||
|
||||
private fun recalculate() {
|
||||
var count = 0
|
||||
var value: Any?
|
||||
|
||||
var minX = 16
|
||||
var minY = 16
|
||||
|
@ -5,12 +5,16 @@ import de.bixilon.minosoft.gui.rendering.system.base.texture.TextureTransparenci
|
||||
object CullUtil {
|
||||
|
||||
fun Array<FaceProperties>.canCull(properties: FaceProperties, sameBlock: Boolean): Boolean {
|
||||
val sizeStartX = properties.sizeStart.x
|
||||
val sizeStartY = properties.sizeStart.y
|
||||
val sizeEndX = properties.sizeEnd.x
|
||||
val sizeEndY = properties.sizeEnd.y
|
||||
for (property in this) {
|
||||
if (
|
||||
property.sizeStart.x <= properties.sizeStart.x
|
||||
&& property.sizeStart.y <= properties.sizeStart.y
|
||||
&& property.sizeEnd.x >= properties.sizeEnd.x
|
||||
&& property.sizeEnd.y >= properties.sizeEnd.y
|
||||
property.sizeStart.x <= sizeStartX
|
||||
&& property.sizeStart.y <= sizeStartY
|
||||
&& property.sizeEnd.x >= sizeEndX
|
||||
&& property.sizeEnd.y >= sizeEndY
|
||||
&& !((properties.transparency == TextureTransparencies.OPAQUE && property.transparency != TextureTransparencies.OPAQUE)
|
||||
|| (properties.transparency != TextureTransparencies.OPAQUE && property.transparency == properties.transparency && !sameBlock)
|
||||
|| (properties.transparency == TextureTransparencies.TRANSPARENT && property.transparency == TextureTransparencies.TRANSLUCENT))
|
||||
|
@ -13,22 +13,17 @@
|
||||
|
||||
package de.bixilon.minosoft.util.task.pool
|
||||
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedSetOf
|
||||
import de.bixilon.minosoft.util.KUtil.synchronizedListOf
|
||||
import de.bixilon.minosoft.util.KUtil.toSynchronizedList
|
||||
import de.bixilon.minosoft.util.KUtil.toSynchronizedSet
|
||||
import java.util.concurrent.Callable
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Future
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.*
|
||||
|
||||
open class ThreadPool(
|
||||
val threadCount: Int = Runtime.getRuntime().availableProcessors(),
|
||||
private val name: String = "Worker#%d",
|
||||
) : ExecutorService {
|
||||
private var state = ThreadPoolStates.STARTING
|
||||
private val threads: MutableSet<Thread> = synchronizedSetOf()
|
||||
private val availableThreads: MutableSet<Thread> = synchronizedSetOf()
|
||||
private var pending: MutableSet<ThreadPoolRunnable> = sortedSetOf<ThreadPoolRunnable>({ a, b -> a.priority - b.priority }).toSynchronizedSet()
|
||||
private var threads: MutableList<Thread> = synchronizedListOf()
|
||||
private var queue: PriorityBlockingQueue<ThreadPoolRunnable> = PriorityBlockingQueue()
|
||||
private var nextThreadId = 0
|
||||
|
||||
init {
|
||||
@ -37,43 +32,24 @@ open class ThreadPool(
|
||||
state = ThreadPoolStates.STARTED
|
||||
}
|
||||
|
||||
val pendingCount: Int
|
||||
get() = pending.size
|
||||
val queueSize: Int
|
||||
get() = queue.size
|
||||
|
||||
@Synchronized
|
||||
private fun checkThreads() {
|
||||
fun wait() {
|
||||
try {
|
||||
availableThreads += Thread.currentThread()
|
||||
Thread.sleep(Long.MAX_VALUE)
|
||||
} catch (exception: InterruptedException) {
|
||||
// Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Thread (${Thread.currentThread()} sleeping got interrupted" }
|
||||
}
|
||||
availableThreads -= Thread.currentThread()
|
||||
}
|
||||
|
||||
for (i in 0 until threadCount - threads.size) {
|
||||
var runnable: ThreadPoolRunnable
|
||||
val thread = Thread {
|
||||
while (true) {
|
||||
if (state == ThreadPoolStates.STOPPING) {
|
||||
break
|
||||
}
|
||||
if (pending.isEmpty()) {
|
||||
wait()
|
||||
try {
|
||||
runnable = queue.take()
|
||||
} catch (exception: InterruptedException) {
|
||||
break
|
||||
}
|
||||
|
||||
val runnable: ThreadPoolRunnable?
|
||||
synchronized(pending) {
|
||||
if (pending.isNotEmpty()) {
|
||||
runnable = pending.iterator().next()
|
||||
pending.remove(runnable)
|
||||
} else {
|
||||
runnable = null
|
||||
}
|
||||
}
|
||||
if (runnable == null) {
|
||||
continue
|
||||
}
|
||||
try {
|
||||
runnable.thread = Thread.currentThread()
|
||||
runnable.runnable.run()
|
||||
@ -83,9 +59,7 @@ open class ThreadPool(
|
||||
if (exception is InterruptedException) {
|
||||
// Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Thread ${Thread.currentThread()} was interrupted" }
|
||||
runnable.wasInterrupted = true
|
||||
if (!runnable.interuptable) {
|
||||
pending += runnable
|
||||
}
|
||||
queue += runnable
|
||||
|
||||
if (state == ThreadPoolStates.STOPPING) {
|
||||
break
|
||||
@ -94,30 +68,18 @@ open class ThreadPool(
|
||||
exception.printStackTrace()
|
||||
}
|
||||
}
|
||||
|
||||
if (pending.isNotEmpty()) {
|
||||
continue
|
||||
}
|
||||
wait()
|
||||
}
|
||||
threads -= Thread.currentThread()
|
||||
}
|
||||
thread.name = name.format(nextThreadId++)
|
||||
threads += thread
|
||||
thread.start()
|
||||
threads += thread
|
||||
}
|
||||
}
|
||||
|
||||
@Synchronized
|
||||
fun execute(runnable: ThreadPoolRunnable) {
|
||||
pending += runnable
|
||||
synchronized(availableThreads) {
|
||||
if (availableThreads.isNotEmpty()) {
|
||||
val thread = availableThreads.iterator().next()
|
||||
availableThreads.remove(thread)
|
||||
thread.interrupt()
|
||||
// Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Interrupting thread $thread" }
|
||||
}
|
||||
}
|
||||
queue += runnable
|
||||
}
|
||||
|
||||
override fun execute(runnable: Runnable) {
|
||||
@ -138,9 +100,7 @@ open class ThreadPool(
|
||||
state = ThreadPoolStates.STOPPING
|
||||
synchronized(threads) {
|
||||
for (thread in threads.toSynchronizedList()) {
|
||||
if (thread.state == Thread.State.TIMED_WAITING) {
|
||||
thread.interrupt()
|
||||
}
|
||||
thread.interrupt()
|
||||
}
|
||||
}
|
||||
while (threads.isNotEmpty()) {
|
||||
@ -156,12 +116,8 @@ open class ThreadPool(
|
||||
thread.interrupt()
|
||||
}
|
||||
}
|
||||
while (threads.isNotEmpty()) {
|
||||
Thread.sleep(1L)
|
||||
}
|
||||
state = ThreadPoolStates.STOPPED
|
||||
|
||||
return mutableListOf() // ToDo
|
||||
return mutableListOf()
|
||||
}
|
||||
|
||||
override fun isShutdown(): Boolean {
|
||||
|
@ -17,7 +17,7 @@ class ThreadPoolRunnable(
|
||||
val priority: Int = ThreadPool.NORMAL,
|
||||
var interuptable: Boolean = false,
|
||||
val runnable: Runnable,
|
||||
) {
|
||||
) : Comparable<ThreadPoolRunnable> {
|
||||
var wasInterrupted = false
|
||||
var thread: Thread? = null
|
||||
|
||||
@ -27,4 +27,8 @@ class ThreadPoolRunnable(
|
||||
// Log.log(LogMessageType.OTHER, LogLevels.VERBOSE){"Interrupting runnable in thread $thread"}
|
||||
}
|
||||
}
|
||||
|
||||
override fun compareTo(other: ThreadPoolRunnable): Int {
|
||||
return priority - other.priority
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user