私はトークンバケットタイプのシングルトンを実装しました。シングルトンは、メモリ要件に基づいてアドミッションコントロールを処理します。 RAMの80%が私のアプリケーションで使用できるように初期化されます。
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()
}
}
どのように並列化していますか?つまり、各イメージを使用可能なコアに分割するか、複数のイメージを並行して処理しますか? –
複数の画像を並行して処理します。私が1つの画像のために作業を並列化できれば、この問題はそれほど重要ではないでしょう。おそらく、私はその道にもっと努力する必要があるかもしれません(1つの画像だけを処理する場合には待ち時間が短くなるという利点もあります)。 – BearOverflow
更新:私が恐れていたことは真実に終わりました。並列化できる部分は並列化のメリットがありません。並列タスクを作成するオーバーヘッドは、CPU効率の利点を取り除きます。この部分の最適な並列化係数は2です(これ以上の利得は得られません)。これは素晴らしいことですが、名目上のユースケースではない大量の画像(8192x8192)との違いが始まります。名目上のユースケースの場合、マイナーな改善はコードの複雑さを保証するものではないと私は思う。だから問題は本当にまだ立っている。 – BearOverflow