在 Swift 中将 [Float] 转换为 [simd_float4]

标签 c swift simd

我有一个从 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 代码时必须进行一些转换,我可以通过使用 ContigouslyArray 来解决这个问题,但我不能使用 ContigouslyArray 来调用 C。

最佳答案

withUnsafe(Mutable)BufferPointer() 可用于获取指向数组(可变)存储的指针,withMemoryRebound() 可用于访问数组>Float 作为 float4 数组:

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]

关于在 Swift 中将 [Float] 转换为 [simd_float4],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53890044/

相关文章:

c - 用 C 语言创建一个带有变量的二维数组

c - doxygen 忽略文件的特殊命令

swift - 如果在洛杉矶,时区为空

线程中的 Swift 3 CFRunLoopRun?

C++ 加载和存储优化和堆对象

c - ARM NEON 内部函数 : Limit values of a vector to 0-255

c - 将C库添加到docker

c - 为什么文件意外更改?

iphone - 第一次接触后立即结束 Sprite 套件碰撞

assembly - 如何将 128 位立即数移至 XMM 寄存器