Hello,
There is some Metal sample code that is written in Objective-C (https://developer.apple.com/documentation/metal/performing_calculations_on_a_gpu). I wanted to implement this in Swift, but am running into a major performance issue.
The sample code fills two large buffers with pseudorandom data, and does so very quickly (a fraction of a second for ~14 million elements) using the rand() function. In my Swift version, I have tried many methods for generating data, but they all take between 6 and 10 seconds for the same ~14 million elements (the rand() function is not available in Swift) on my M1 Pro.
Surely there must be some method in Swift that can approximate the general speed of rand(). I'm more than willing to trade randomness for speed!
Any ideas?
Good idea about changing the Obj-C code to use arc4random() instead of rand(). I did so, and have found that for the 16.7 million floats (1 << 24) in Apple's sample code, rand() takes about 0.13 second, while arc4random() takes about 1.25 seconds.
I tried a few more things with the Swift code that have produced some very interesting results. Switching from for in to a while < loop drastically reduces the execution time.
let randomRange: ClosedRange<Float> = 0...Float(100.0)
let arrayLength = (1 << 24)
var buffer: [Float] = Array(repeating: 0.0, count: arrayLength)
var idx: Int = 0
while idx < arrayLength {
buffer[idx] = Float.random(in: randomRange)
idx += 1
}
The loop in the above code runs in 5.12 seconds - less than half the time that for idx in 0..<arrayLength takes!
This promising result led me back to using GameplayKit.
let arrayLength = (1 << 24)
let randomSource = GKLinearCongruentialRandomSource()
var buffer: [Float] = Array(repeating: 0.0, count: arrayLength)
var idx: Int = 0
while idx < arrayLength {
buffer[idx] = Float(randomSource.nextInt())/Float(RAND_MAX)
idx += 1
}
The loop in the above code runs in 0.86 seconds!
This is still significantly slower than rand(), but I'm fine with it. I may look more into other implementations in the future.
I appreciate the feedback and suggestions. It really helped get me thinking.