Swift 5.1 で追加された SIMD の機能
忘れていたのでまとめてみる。
Swift でビルトイン実装されている SMID の機能と Swift Standard Library で SMID を引数として持つ関数が追加された。
追加されたものは以下のもの
SIMD
- one
- clamp(lowerBound:upperBound:)
- max()
- min()
- sum()
- wrappedSum()
- hashValue
- scalarCount
- subscript(_:)
- イニシャライズ時に ArrayLiteralElement のサポート
SIMD3、SIMD4 のみ
- init(_ xy: SIMD2
, _ z: Scalar) - init(_ xyz: SIMD3
, _ w: Scalar)
Swift Standard Library
- any(_:)
- all(_:)
- pointwiseMax(::)
- pointwiseMin(::)
内容説明
以下、特に記載がなければ、SIMD2 〜 64 と全ての型 (Scalar) を対応。
SIMD の説明はしないので前回を参照。
one
以前にあった zero はレーンを 0 で埋めるものだがこちらは 1 で埋めていく。
let s = SIMD4<Float>.one // SIMD4<Float>(1.0, 1.0, 1.0, 1.0)
clamp(lowerBound:upperBound:)
指定された2レーンの中から上限値と下限値内に収まるように各値を変更する。
let s1 = SIMD4<Float>(1.1, 2.2, 3.3, 4.4) let s2 = s1.clamped( lowerBound: SIMD4<Float>(2,2,2,2), upperBound: SIMD4<Float>(4,4,4,4) ) // SIMD4<Float>(2.0, 2.2, 3.3, 4.0)
max()
min()
レーンの中から最大値や最小値を調べその値を返す。
let s = SIMD4<Float>(1.1, 2.2, 3.3, 4.4) s.max() // 4.4 s.min() // 1.1
sum()
wrappedSum()
sum() は FloatingPoint を返し、wrappedSum() は FixedWidthInteger を返す。
そのため、型 (Scalar) が浮動小数点数の場合は sum()、
整数の場合は wrappedSum() が使用可能。
let s1 = SIMD4<Float>(0.0, 1.1, 2.2, 3.3) let s2 = SIMD16<Int>(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) s1.sum() // 6.6 s2.wrappedSum() // 120
hashValue
ハッシュ値を返す。
let s1 = SIMD4<Int>(0,1,2,4) s1.hashValue // -8324632633033442855 など
scalarCount
Scalar が幾つの SIMD か調べることができる。
let s1 = SIMD4<Int>(0,1,2,3) let s2 = SIMD16<Int>(0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15) s1.scalarCount // 4 s2.scalarCount // 16
subscript(_:)
FixedWidthInteger の SIMD を添え字として使用し対象の SIMD の値を取り出し、
新しい値の入ったレーンを取得できる。
let s1 = SIMD2<Int>(3,2) let s2 = SIMD4<Float>(0.1, 0.2, 0.3, 0.4) let s3 = s2[s1] // SIMD2<Float>(0.4, 0.3)
イニシャライズ時に ArrayLiteralElement のサポート
配列の記述を使用し、SIMD イニシャライズすることが可能になった。
SIMD2 〜 64、全ての型 (Scalar) を対応。
let a2:[Float] = [1,2] let a3:[Float] = [1,2,3] let a4:[Float] = [1,2,3,4] let a8:[Float] = [1,2,3,4,5,6,7,8] let s2 = SIMD2<Float>(a2) let s3 = SIMD3<Float>(a3) let s4 = SIMD4<Float>(a4) let s8 = SIMD8<Float>(a8)
init(_ xy: SIMD2, _ z: Scalar)
init(_ xyz: SIMD3, _ w: Scalar)
init(_ xyz: SIMD3
SIMD3、SIMD4 のみ、SIMD2、SIMD3 と最後の値を足すことでイニシャライズできる関数が追加された。
let s2 = SIMD2<Float>.zero // SIMD2<Float>(0.0, 0.0) let s3 = SIMD3<Float>(s2, 3) // SIMD3<Float>(0.0, 0.0, 3.0) let s4 = SIMD4<Float>(s3, 4) // SIMD4<Float>(0.0, 0.0, 3.0, 4.0)
any(_:)
all(_:)
SIMDMask の Bool を使い状態を判別する関数。
any はレーンのいずれかが true であれば true、
all はレーンの全てが true であれば true を返す
let s8 = SIMD8<Float>(1,2,3,4,5,6,7,8) any(s8 .< 3) // true all(s8 .< 7) // false all(s8 .< 9) // true
pointwiseMin(_:_:)
pointwiseMax(_:_:)
2つのレーンを調べその中の最大値や最小値を設定したレーンを返す。
let s1 = SIMD3(0,1,2) let s2 = SIMD3(2,1,0) pointwiseMin(s1, s2) // SIMD3<Int>(0, 1, 0) pointwiseMax(s1, s2) // SIMD3<Int>(2, 1, 2)
廃止になったもの
- init(Self.Scalar)
- static func - (Self) -> Self
以上、更新の内容。
実は前回のやつ全て書いてないので全部紹介しきれていないけど