我最终实现了一个TokenBucket类型的单例,它根据内存需求来处理准入控制。它被初始化,以便我的应用程序可以使用80%的RAM。
let memoryGate = MemoryGate(maxBytes: ProcessInfo.processInfo.physicalMemory*8/10)
当有人想执行内存密集型操作时,它必须从中请求()内存。如果没有足够的存储空间,则会阻止通话。完成后,线程必须释放()内存。
代码:
class MemoryGate {
private let maxBytes : UInt64
private var availableBytes : Int64
private let cv = NSCondition()
init(maxBytes: UInt64) {
self.maxBytes = maxBytes
self.availableBytes = Int64(maxBytes)
Log.debug?.message("maxBytes=\(maxBytes)")
}
public func request(amount: UInt64) {
Log.debug?.message("Resquesting \(amount) bytes")
cv.lock()
// If the amount is bigger than the max allowed, no amount of waiting is going
// to help, so we go through and let the other smaller jobs be held back until
// memory is freed
if (amount <= maxBytes) {
while (availableBytes < Int64(amount)) {
cv.wait()
}
}
availableBytes -= Int64(amount)
Log.debug?.message("Got \(amount) bytes. availableBytes=\(availableBytes)")
cv.unlock()
}
public func release(amount: UInt64) {
cv.lock()
availableBytes += Int64(amount)
Log.debug?.message("Released \(amount) bytes. availableBytes=\(availableBytes)")
cv.broadcast()
cv.unlock()
}
}
你如何并行?我的意思是你是否在可用内核之间分割每个映像,或者是否同时处理多个映像? –
我并行处理多个图像。如果我可以并行处理一个图像的工作,这个问题就不会那么重要。也许我需要在这条道路上投入更多的精力(当我们只处理一幅图像时,它也有较低的延迟),但问题依然存在。 – BearOverflow
更新:我害怕的结果是真实的 - 可并行化的部分并没有从并行化中获益。创建并行任务的开销消除了CPU效率增益的优势。这部分最好的并行化因素是2(除此之外没有更多的收益),这很好,但它只是开始与大量图像(8192x8192)产生差异,这不是标称使用情况。对于名义用例,我认为小的改进并不能保证所产生的代码复杂性。所以这个问题依然存在。 – BearOverflow