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.