Last active
January 25, 2018 21:00
-
-
Save qRoC/bd109ca83c15199caaa069d8f5d1d396 to your computer and use it in GitHub Desktop.
Swift simd matrix init bench Raw
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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