- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
我正在尝试确定创建我自己的连续内存容器的“Swift-y”方式(在我的特定情况下,我正在构建 n 维数组)。我希望我的容器在功能和可用性方面尽可能接近 Swift 的内置数组。
我需要访问指向我的容器内存的指针,以进行 Accelerate 和 BLAS 操作。
我想知道 ArraySlice 的指针是指向切片的第一个元素,还是指向其基址的第一个元素。
当我尝试测试 UnsafePointer<Int>(array) == UnsafePointer<Int>(array[1...2])
时看起来 Swift 不允许从 ArraySlices 构造指针(或者我只是做错了)。
我正在寻找关于哪种方式最“Swift-y”的建议?
我知道在对数组进行切片时,以下内容是正确的:
let array = [1, 2, 3]
array[1] == array[1...2][1]
和
array[1...2][0] != 2 # index out of bounds error
换句话说,索引总是相对于基本数组执行的。
这表明:我们应该返回一个指向基的第一个元素的指针。因为切片是相对于它们的基数的。
但是,遍历切片(显然)只考虑该切片的元素:
for i in array[1..2] # i takes on 2 followed by 3
这表明:我们应该返回一个指向切片第一个元素的指针。因为切片有自己的起点。
如果我的用户想在 BLAS 操作中对切片进行操作,则可以直观地预期:
mmul(matrix1[1...2, 0...1].pointer, matrix2[4...5, 0...1].pointer)
指向 slice 的第一个元素,但我不知道这是否是 Swift ArraySlice 做事的方式。
我的问题:容器切片对象的指针应该指向切片的第一个元素,还是基础容器的第一个元素。
最佳答案
这个操作是不安全的:
UnsafePointer<Int>(array)
你的意思是:
array.withUnsafeBufferPointer { ... }
这也适用于您的类型,并且是您应该用来与 BLAS 和 Accelerate 进行互操作的模式。你不应该尝试使用 pointer
方法 IMO。
没有 promise array
将在您实际访问指针时继续存在,即使这发生在同一行代码中。 ARC 可以自由地以惊人的速度摧毁那段内存。
UnsafeBufferPointer
实际上是一个非常好的类型,因为它已经 promise 是连续的,并且它的行为就像一个集合。
我的建议是在内部管理您自己的内存,可能使用 ManagedBuffer
, 但也许只是一个 UnsafeMutablePointer
那你alloc
和 destroy
你自己。管理数据布局以使其与 Accelerate 兼容非常重要。你不想要 Array<Array<UInt8>>
.那会增加太多的结构。您需要以良好的 C 方式(行*宽度+列等)索引到的字节 block 。您可能根本不希望切片直接返回指针。你的mmul
函数可能需要特殊的逻辑来理解如何通过最少的复制将它需要的部分从切片中拉出来,以便它与 vDSP_mmul
一起工作。 . “通用”和“加速”很少一起出现。
例如,考虑到这一点:
mmul(matrix1[1...2, 0...1].pointer, matrix2[4...5, 0...1].pointer)
(显然,我假设您的真实矩阵要大得多;这种矩阵发送到 vDSP 没有多大意义。)
您将不得不编写自己的 mmul
很明显,因为这个内存布局不正确。所以你不妨把切片传过去。然后你会做类似的事情(完全未经测试,未经编译,我确信语法是错误的):
mmul(m1: MatrixSlice, m2: MatrixSlice) -> Matrix {
var s1 = UnsafeMutablePointer<Float>.alloc(m1.rows * m1.columns)
// use vDSP_vgathr to copy each sliced row out of m1 into s1
var s2 = UnsafeMutablePointer<Float>.alloc(m2.rows * m2.columns)
// use vDSP_vgathr to copy each sliced row out of m2 into s2
var result = UnsafeMutablePointer<Float>.alloc(m1.rows * m2.columns)
vDSP_mmul(s1, 1, s2, 1, result, 1, m1.rows, m2.columns, m1.columns)
s1.destroy()
s2.destroy()
// This will need to call result.move() or moveInitializeFrom or something
return Matrix(result)
}
我只是在这里扔东西,但这可能是您想要的那种结构。
关于指向容器或数据的指针是否通常由 Swift 传递的基本问题,不幸的是,答案对于 Array 来说是“神奇的”,而不是其他任何人。将数组传递给需要指针的对象会神奇地(通过编译器,而不是标准库)将指针传递给数组的存储。没有其他类型的人有这种魔力。甚至没有ContiguousArray
得到这个魔法。如果你传递一个 ContiguousArray
对于需要指针的东西,您会将指针传递给容器(如果它是可变的,则破坏容器;真实的故事,讨厌那个……)
关于来自 ArraySlice 的 Swift 指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34663500/
我刚接触 C 语言几周,所以对它还很陌生。 我见过这样的事情 * (variable-name) = -* (variable-name) 在讲义中,但它到底会做什么?它会否定所指向的值吗? 最佳答案
我有一个指向内存地址的void 指针。然后,我做 int 指针 = void 指针 float 指针 = void 指针 然后,取消引用它们以获取值。 { int x = 25; vo
我正在与计算机控制的泵进行一些串行端口通信,我用来通信的 createfile 函数需要将 com 端口名称解析为 wchar_t 指针。 我也在使用 QT 创建一个表单并获取 com 端口名称作为
#include "stdio.h" #include "malloc.h" int main() { char*x=(char*)malloc(1024); *(x+2)=3; --
#include #include main() { int an_int; void *void_pointer = &an_int; double *double_ptr = void
对于每个时间步长,我都有一个二维矩阵 a[ix][iz],ix 从 0 到 nx-1 和 iz 从 0 到 nz-1。 为了组装所有时间步长的矩阵,我定义了一个长度为 nx*nz*nt 的 3D 指针
我有一个函数,它接受一个指向 char ** 的指针并用字符串填充它(我猜是一个字符串数组)。 *list_of_strings* 在函数内部分配内存。 char * *list_of_strings
我试图了解当涉及到字符和字符串时,内存分配是如何工作的。 我知道声明的数组的名称就像指向数组第一个元素的指针,但该数组将驻留在内存的堆栈中。 另一方面,当我们想要使用内存堆时,我们使用 malloc,
我有一个 C 语言的 .DLL 文件。该 DLL 中所有函数所需的主要结构具有以下形式。 typedef struct { char *snsAccessID; char *
我得到了以下数组: let arr = [ { children: [ { children: [], current: tru
#include int main(void) { int i; int *ptr = (int *) malloc(5 * sizeof(int)); for (i=0;
我正在编写一个程序,它接受一个三位数整数并将其分成两个整数。 224 将变为 220 和 4。 114 将变为 110 和 4。 基本上,您可以使用模数来完成。我写了我认为应该工作的东西,编译器一直说
好吧,我对 C++ 很陌生,我确定这个问题已经在某个地方得到了回答,而且也很简单,但我似乎找不到答案.... 我有一个自定义数组类,我将其用作练习来尝试了解其工作原理,其定义如下: 标题: class
1) this 指针与其他指针有何不同?据我了解,指针指向堆中的内存。如果有指向它们的指针,这是否意味着对象总是在堆中构造? 2)我们可以在 move 构造函数或 move 赋值中窃取this指针吗?
这个问题在这里已经有了答案: 关闭 11 年前。 Possible Duplicate: C : pointer to struct in the struct definition 在我的初学者类
我有两个指向指针的结构指针 typedef struct Square { ... ... }Square; Square **s1; //Representing 2D array of say,
变量在内存中是如何定位的?我有这个代码 int w=1; int x=1; int y=1; int z=1; int main(int argc, char** argv) { printf
#include #include main() { char *q[]={"black","white","red"}; printf("%s",*q+3); getch()
我在“C”类中有以下函数 class C { template void Func1(int x); template void Func2(int x); }; template void
我在64位linux下使用c++,编译器(g++)也是64位的。当我打印某个变量的地址时,例如一个整数,它应该打印一个 64 位整数,但实际上它打印了一个 48 位整数。 int i; cout <<
我是一名优秀的程序员,十分优秀!