수백만 개의 계산을 수행해야하는 매우 큰 배열이 있습니다. Objective-C에서 배열은 NSData로 저장 될 것이고 나는 (합계, 더하기 등)에 Accelerate 함수를 사용하기 위해 C 배열로 추상화 할 것입니다. 그러나 (모든 곳에서 포인터를 사용하는 것과 관련된 명백한 문제가 있음) 스위프트 배열이 내장되어 있는지 확인하는 경계를 더 많이 사용하고 싶습니다. 따라서 두 배열을 사용하기 위해 중첩 된 withUnsafeBufferPointer를 사용할 수 있습니다.Accelerate 기능으로 ArraySlice를 사용하는 더 나은 방법은 무엇입니까?
func mult(_ x: ArraySlice<Double>, _ y: ArraySlice<Double>) -> [Double] {
assert(x.count == y.count)
var results = [Double](repeating:0, count: x.count)
x.withUnsafeBufferPointer({xBuffer in
y.withUnsafeBufferPointer({yBuffer in
vDSP_vmulD([Double](xBuffer), 1, [Double](yBuffer), 1, &results, 1, vDSP_Length(xBuffer.count))
})
})
return results
}
var testArray = [Double]([0,1,2,3,4,5,6,7,8,9,10])
var testArray2 = [Double]([2,2,2,2,2,2,2,2,2,2,2])
let results = mult(testArray[5...10], testArray2[5...10])
print("\(results)")
첫째, 컴파일러는 이미 캐스팅하는 방법을 알고 때 의도 한 형식이 이상한 것 같이 참 -_-에게 포인터를 갖는 [더블] 자체 (블록 내부에 전달 된 포인터 VDSP 기능 반면, 유형 UnsafeBufferPointer<Double>
의입니다 UnsafePointer<Double>
이 필요합니다 (배열 변수 자체를 전달하면 불만 없습니다). 둘째, 사용법을 이해하고 있지만 withUnsafeBufferPointer
을 중첩해야한다는 것이 이상하게 보입니다. 마지막으로, ArraySlice<Double>
을 입력 매개 변수 유형으로 사용하면 Double 배열과 해당 배열의 조각 모두에 함수를 일반화 할 수 없습니다.
더 좋은 방법이 있나요?
나는 프로토콜을 생각해 봤어야했다. (나는 계속 제네릭을 사용하는 다른 방법을 시도했다.) 내가 혼란스러워하는 한 가지는 프로토콜이'count'를 가져야 만하는 이유입니다 (결과 배열은'x.count'가 유효하지 않다고 불평하기 때문에 결과 배열을 선언 할 수 없습니다). 'baseAddress'를 가지고 있습니다. 설명해 주시겠습니까? –
@AdamJones 그것은'withUnsafeBufferPointer'의'x' 변수가 그 바깥 쪽의'x'와 같지 않기 때문에 그림자가 생깁니다. 'x'를 클릭하면 그것을 볼 수 있습니다. 'x' 대신에'xBuf'를 선택할 수 있습니다.''BaseAddress'' 속성을 가진'UnsafeBufferPointer'입니다. – Kametrixom
Gotcha. 고마워요. –