Skip to content

Instantly share code, notes, and snippets.

@qRoC
Last active January 25, 2018 21:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qRoC/bd109ca83c15199caaa069d8f5d1d396 to your computer and use it in GitHub Desktop.
Save qRoC/bd109ca83c15199caaa069d8f5d1d396 to your computer and use it in GitHub Desktop.
Swift simd matrix init bench Raw
import simd
import Foundation
import Darwin
public enum Random {
public static func unit() -> Float32 {
return Float32(arc4random()) / Float32(UInt32.max)
}
}
public extension float3x3 {
var inverse2: float3x3 {
var inverse = float3x3(0)
inverse[0, 0] = self[1, 1] * self[2, 2] - self[2, 1] * self[1, 2]
inverse[0, 1] = self[2, 1] * self[0, 2] - self[0, 1] * self[2, 2]
inverse[0, 2] = self[0, 1] * self[1, 2] - self[1, 1] * self[0, 2]
inverse[1, 0] = self[2, 0] * self[1, 2] - self[1, 0] * self[2, 2]
inverse[1, 1] = self[0, 0] * self[2, 2] - self[2, 0] * self[0, 2]
inverse[1, 2] = self[1, 0] * self[0, 2] - self[0, 0] * self[1, 2]
inverse[2, 0] = self[1, 0] * self[2, 1] - self[2, 0] * self[1, 1]
inverse[2, 1] = self[2, 0] * self[0, 1] - self[0, 0] * self[2, 1]
inverse[2, 2] = self[0, 0] * self[1, 1] - self[1, 0] * self[0, 1]
let determinant = self[0, 0] * inverse[0, 0] +
self[1, 0] * inverse[0, 1] +
self[2, 0] * inverse[0, 2]
if abs(determinant) <= 1E-6 {
return inverse // false
}
let invDeterminant = 1 / determinant
return inverse * invDeterminant // true
}
var inverse3: float3x3 {
let m00 = self[1, 1] * self[2, 2] - self[2, 1] * self[1, 2]
let m01 = self[2, 1] * self[0, 2] - self[0, 1] * self[2, 2]
let m02 = self[0, 1] * self[1, 2] - self[1, 1] * self[0, 2]
let m10 = self[2, 0] * self[1, 2] - self[1, 0] * self[2, 2]
let m11 = self[0, 0] * self[2, 2] - self[2, 0] * self[0, 2]
let m12 = self[1, 0] * self[0, 2] - self[0, 0] * self[1, 2]
let m20 = self[1, 0] * self[2, 1] - self[2, 0] * self[1, 1]
let m21 = self[2, 0] * self[0, 1] - self[0, 0] * self[2, 1]
let m22 = self[0, 0] * self[1, 1] - self[1, 0] * self[0, 1]
var inverse = float3x3([
float3(m00, m01, m02),
float3(m10, m11, m12),
float3(m20, m21, m22)
])
let determinant = self[0, 0] * inverse[0, 0] +
self[1, 0] * inverse[0, 1] +
self[2, 0] * inverse[0, 2]
if abs(determinant) <= 1E-6 {
return inverse // false
}
let invDeterminant = 1 / determinant
return inverse * invDeterminant // true
}
var inverse4: float3x3 {
let m00 = self[1, 1] * self[2, 2] - self[2, 1] * self[1, 2]
let m01 = self[2, 1] * self[0, 2] - self[0, 1] * self[2, 2]
let m02 = self[0, 1] * self[1, 2] - self[1, 1] * self[0, 2]
let m10 = self[2, 0] * self[1, 2] - self[1, 0] * self[2, 2]
let m11 = self[0, 0] * self[2, 2] - self[2, 0] * self[0, 2]
let m12 = self[1, 0] * self[0, 2] - self[0, 0] * self[1, 2]
let m20 = self[1, 0] * self[2, 1] - self[2, 0] * self[1, 1]
let m21 = self[2, 0] * self[0, 1] - self[0, 0] * self[2, 1]
let m22 = self[0, 0] * self[1, 1] - self[1, 0] * self[0, 1]
var inverse = float3x3(columns: (
float3(m00, m01, m02),
float3(m10, m11, m12),
float3(m20, m21, m22)
))
let determinant = self[0, 0] * inverse[0, 0] +
self[1, 0] * inverse[0, 1] +
self[2, 0] * inverse[0, 2]
if abs(determinant) <= 1E-6 {
return inverse // false
}
let invDeterminant = 1 / determinant
return inverse * invDeterminant // true
}
var inverse5: float3x3 {
let m00 = self[1, 1] * self[2, 2] - self[2, 1] * self[1, 2]
let m01 = self[2, 0] * self[1, 2] - self[1, 0] * self[2, 2]
let m02 = self[1, 0] * self[2, 1] - self[2, 0] * self[1, 1]
let m10 = self[2, 1] * self[0, 2] - self[0, 1] * self[2, 2]
let m11 = self[0, 0] * self[2, 2] - self[2, 0] * self[0, 2]
let m12 = self[2, 0] * self[0, 1] - self[0, 0] * self[2, 1]
let m20 = self[0, 1] * self[1, 2] - self[1, 1] * self[0, 2]
let m21 = self[1, 0] * self[0, 2] - self[0, 0] * self[1, 2]
let m22 = self[0, 0] * self[1, 1] - self[1, 0] * self[0, 1]
var inverse = float3x3(rows: [
float3(m00, m01, m02),
float3(m10, m11, m12),
float3(m20, m21, m22)
])
let determinant = self[0, 0] * inverse[0, 0] +
self[1, 0] * inverse[0, 1] +
self[2, 0] * inverse[0, 2]
if abs(determinant) <= 1E-6 {
return inverse // false
}
let invDeterminant = 1 / determinant
return inverse * invDeterminant // true
}
var inverse6: float3x3 {
let m00 = self[1, 1] * self[2, 2] - self[2, 1] * self[1, 2]
let m01 = self[2, 1] * self[0, 2] - self[0, 1] * self[2, 2]
let m02 = self[0, 1] * self[1, 2] - self[1, 1] * self[0, 2]
let m10 = self[2, 0] * self[1, 2] - self[1, 0] * self[2, 2]
let m11 = self[0, 0] * self[2, 2] - self[2, 0] * self[0, 2]
let m12 = self[1, 0] * self[0, 2] - self[0, 0] * self[1, 2]
let m20 = self[1, 0] * self[2, 1] - self[2, 0] * self[1, 1]
let m21 = self[2, 0] * self[0, 1] - self[0, 0] * self[2, 1]
let m22 = self[0, 0] * self[1, 1] - self[1, 0] * self[0, 1]
var inverse = float3x3(
float3(m00, m01, m02),
float3(m10, m11, m12),
float3(m20, m21, m22)
)
let determinant = self[0, 0] * inverse[0, 0] +
self[1, 0] * inverse[0, 1] +
self[2, 0] * inverse[0, 2]
if abs(determinant) <= 1E-6 {
return inverse // false
}
let invDeterminant = 1 / determinant
return inverse * invDeterminant // true
}
/// https://forums.swift.org/t/creating-a-simd-floatnxn-from-array-is-very-slow/8796/6?u=qroc
init(fromArray array: [float3]) {
precondition(array.count == 3, "float3x3 requires an array with 3 elements.")
self.init(columns: (array[0], array[1], array[2]))
}
var inverse7: float3x3 {
let m00 = self[1, 1] * self[2, 2] - self[2, 1] * self[1, 2]
let m01 = self[2, 1] * self[0, 2] - self[0, 1] * self[2, 2]
let m02 = self[0, 1] * self[1, 2] - self[1, 1] * self[0, 2]
let m10 = self[2, 0] * self[1, 2] - self[1, 0] * self[2, 2]
let m11 = self[0, 0] * self[2, 2] - self[2, 0] * self[0, 2]
let m12 = self[1, 0] * self[0, 2] - self[0, 0] * self[1, 2]
let m20 = self[1, 0] * self[2, 1] - self[2, 0] * self[1, 1]
let m21 = self[2, 0] * self[0, 1] - self[0, 0] * self[2, 1]
let m22 = self[0, 0] * self[1, 1] - self[1, 0] * self[0, 1]
var inverse = float3x3(fromArray: [
float3(m00, m01, m02),
float3(m10, m11, m12),
float3(m20, m21, m22)
])
let determinant = self[0, 0] * inverse[0, 0] +
self[1, 0] * inverse[0, 1] +
self[2, 0] * inverse[0, 2]
if abs(determinant) <= 1E-6 {
return inverse // false
}
let invDeterminant = 1 / determinant
return inverse * invDeterminant // true
}
}
let matrix = float3x3(
float3(Random.unit(), Random.unit(), Random.unit()),
float3(Random.unit(), Random.unit(), Random.unit()),
float3(Random.unit(), Random.unit(), Random.unit())
)
func printTimeElapsedWhenRunningCode(title: String, operation: () -> ()) {
let startTime = CFAbsoluteTimeGetCurrent()
operation()
let timeElapsed = CFAbsoluteTimeGetCurrent() - startTime
print("Time elapsed for \(title): \(timeElapsed) s.")
}
let maxIterations = Int(Random.range(from: 50000000.01, to: 50000000.1))
// ============
// Warming up
var res1 = matrix
for _ in 0...maxIterations {
res1 += res1.inverse
}
var res2 = matrix
for _ in 0...maxIterations {
res2 += res2.inverse2
}
var res3 = matrix
for _ in 0...maxIterations {
res3 += res3.inverse3
}
var res4 = matrix
for _ in 0...maxIterations {
res4 += res4.inverse4
}
var res5 = matrix
for _ in 0...maxIterations {
res5 += res5.inverse5
}
var res6 = matrix
for _ in 0...maxIterations {
res6 += res6.inverse6
}
var res7 = matrix
for _ in 0...maxIterations {
res7 += res7.inverse7
}
// ============
// Bench
printTimeElapsedWhenRunningCode(title: "inverse") {
for _ in 0...maxIterations {
res1 += res1.inverse
}
}
printTimeElapsedWhenRunningCode(title: "inverse2") {
for _ in 0...maxIterations {
res2 += res2.inverse2
}
}
printTimeElapsedWhenRunningCode(title: "inverse3") {
for _ in 0...maxIterations {
res3 += res3.inverse3
}
}
printTimeElapsedWhenRunningCode(title: "inverse4") {
for _ in 0...maxIterations {
res4 += res4.inverse4
}
}
printTimeElapsedWhenRunningCode(title: "inverse5") {
for _ in 0...maxIterations {
res5 += res5.inverse5
}
}
printTimeElapsedWhenRunningCode(title: "inverse6") {
for _ in 0...maxIterations {
res6 += res6.inverse6
}
}
printTimeElapsedWhenRunningCode(title: "inverse7") {
for _ in 0...maxIterations {
res7 += res7.inverse7
}
}
if res2 != res1 {
print("res2 fail")
}
if res3 != res1 {
print("res3 fail")
}
if res4 != res1 {
print("res4 fail")
}
if res5 != res1 {
print("res5 fail")
}
if res6 != res1 {
print("res6 fail")
}
if res7 != res1 {
print("res7 fail")
}
Build flags: --configuration release
swiftc: -Ounchecked -gnone -whole-module-optimization -static-stdlib
Time elapsed for inverse: 2.64717900753021 s.
Time elapsed for inverse2: 1.35483705997467 s.
Time elapsed for inverse3: 11.727156996727 s.
Time elapsed for inverse4: 1.38384604454041 s.
Time elapsed for inverse5: 11.8544869422913 s.
Time elapsed for inverse6: 1.38975405693054 s.
Time elapsed for inverse7: 1.37177407939121 s.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment