我有一个从Swift调用的c函数,但我认为应该可以在Swift中实现,诀窍是能够将float数组的内存转换为simd_float4数组。下面是我的c函数以及如何在Swift中调用它
迅速
sumFloats(&y, y1, n, anAmplitudes[z]);
C
void sumFloats(float * y, const float * x, const int yc, const float a) {
simd_float4 theA = simd_make_float4(a,a,a,a);
simd_float4 * theY = (simd_float4*)y;
simd_float4 * theX = (simd_float4*)x;
assert( (yc&0x3) == 0 );
for( int t = 0, theYC = yc >> 2; t < theYC; t ++ ) {
theY[t] += theA * theX[t];
}
}
我的理解是数组不能保证连续的内存块,因此在调用C代码时必须进行一些转换,我可以通过使用ContiguousArray来解决此问题,但不能使用ContiguousArray来解决。打电话给C。
答案 0 :(得分:1)
withUnsafe(Mutable)BufferPointer()
可用于获取指向数组(可变)存储的指针,而withMemoryRebound()
可作为Float
的数组访问float4
的数组:< / p>
func sumFloats(y: inout [Float], x: [Float], yc: Int, a: Float) {
let theA = simd_float4(a, a, a, a)
x.withUnsafeBufferPointer {
$0.baseAddress!.withMemoryRebound(to: simd_float4.self, capacity: yc / 4) { theX in
y.withUnsafeMutableBufferPointer {
$0.baseAddress!.withMemoryRebound(to: simd_float4.self, capacity: yc / 4) { theY in
for t in 0..<yc/4 {
theY[t] = theA * theX[t]
}
}
}
}
}
}
示例:
let x: [Float] = [1, 2, 3, 4, 5, 6, 7, 8]
var y: [Float] = [0, 0, 0, 0, 0, 0, 0, 0]
sumFloats(y: &y, x: x, yc: 8, a: 2.0)
print(y) // [2.0, 4.0, 6.0, 8.0, 10.0, 12.0, 14.0, 16.0]
答案 1 :(得分:0)
看看苹果如何定义vForce函数,Martin R的答案可以简化为;
func sumFloats(y: UnsafeMutablePointer<Float>, x: UnsafePointer<Float>, yc: Int, a: Float) {
let theA = simd_float4(a, a, a, a)
x.withMemoryRebound(to: simd_float4.self, capacity: yc / 4) { theX in
y.withMemoryRebound(to: simd_float4.self, capacity: yc / 4) { theY in
for t in 0..<yc/4 {
theY[t] += theA * theX[t]
}
}
}
}
,仍然可以使用[Float]参数以相同的方式调用它。