Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/swift/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Parallel processing Swift中的并行for循环_Parallel Processing_Swift - Fatal编程技术网

Parallel processing Swift中的并行for循环

Parallel processing Swift中的并行for循环,parallel-processing,swift,Parallel Processing,Swift,与以下C&OpenMP代码最接近的Swift等价物是什么(假设n很大而f很简单): #openmp并行 对于(int i=0;i中的Void //做事 }); 您可以将Swift数组转换为NSArray并使用EnumerateObjectsSwithOptions,而无需桥接-请参见下面的简单示例: let kCompanyListFileNames :[String] = [ "nyse_companylist", "nasdaq_companylist", "amex_compa

与以下C&OpenMP代码最接近的Swift等价物是什么(假设
n
很大而
f
很简单):

#openmp并行
对于(int i=0;i
对于这样一个常规任务,将for循环与striding和
dispatch\u apply
并行似乎需要大量的工作。有什么聪明的快捷方式吗?

从iBook上看,似乎还没有针对并行性的特定于swift的API/语言功能。就性能而言,使用GCD似乎是目前最好的选择。如果您希望代码简洁,可以使用标准的Objective-C习惯用法进行并发数组枚举:

    var array : Int[] = [1,2,3,4]
    array.bridgeToObjectiveC().enumerateObjectsWithOptions(NSEnumerationOptions.Concurrent, {(obj: AnyObject!, index: Int, outStop: CMutablePointer<ObjCBool>) -> Void in
        // Do stuff
    });
var数组:Int[]=[1,2,3,4]
array.BridgeToObjective().enumerateObjectsWithOptions(NSEnumerationOptions.Concurrent,{(obj:AnyObject!,index:Int,outStop:CMutablePointer)->中的Void
//做事
});

您可以将Swift数组转换为
NSArray
并使用
EnumerateObjectsSwithOptions
,而无需桥接-请参见下面的简单示例:

let kCompanyListFileNames :[String] = [
  "nyse_companylist",
  "nasdaq_companylist",
  "amex_companylist"
]

let companyListFileNames:NSArray = kCompanyListFileNames as NSArray

companyListFileNames.enumerateObjectsWithOptions(NSEnumerationOptions.Concurrent) {
      (companyName:AnyObject!, index:Int, stop:UnsafeMutablePointer<ObjCBool>) -> Void in
      println(companyName)
    }
让kCompanyListFileName:[字符串]=[
“纽约证券交易所公司列表”,
“纳斯达克大学公司列表”,
“美国运通公司列表”
]
让companyListFileNames:NSArray=kCompanyListFileNames作为NSArray
companyListFileNames.enumerateObjectsWithOptions(NSEnumerationOptions.Concurrent){
(公司名称:AnyObject!,索引:Int,停止:UnsafeMutablePointer)->Void in
println(公司名称)
}

如果您的代码有循环,并且每次通过循环完成的工作与其他迭代中所做的工作无关,那么您可以考虑使用DeXCHCHYApple或DeXCHCHOPAPYYF函数重新实现循环代码。这些函数将循环的每个迭代分别提交给调度队列进行处理。当与并发队列结合使用时,此功能允许您同时执行循环的多个迭代

请看这里:

对于swift:


用于swift中for循环的并行性。您必须使用DispatchQueue.concurrentPerform(计算:执行:)

以上答案中关于使用
concurrentPerform
的线索是正确的,但没有扩展。下面是简单的解决方案:

class ConcurrentCalculator<T> {

    func calc(for b: [T], _ f: (T) -> T) -> [T?] {

        let n = b.count

        var a: [T?] = Array(repeating: nil, count: n)

        DispatchQueue.concurrentPerform(iterations: n) { i in

            a[i] = f(b[i])
        }

        return a
    }
}
当然,这是一个基本的解决方案:它不是线程安全的,而且它可能会遇到大型阵列的内存问题。这可以在以后添加


这种方法的美妙之处在于,您不需要计算可用线程数等。它只会使用所有可用线程。

我非常有兴趣看到将这种方法与(1)简单的单线程Swift实现和(2)OpenMP并行C实现进行比较的基准测试!如果单线程swift实现的性能优于OpenMP,那么首先工作负载对于并行化来说是一个不好的候选者。如果OpenMP版本优于单线程swift,那么。。。这并不奇怪,真的。我认为更有趣的比较应该是使用GCD进行并行性的swift与使用OpenMP的C。(我希望对于足够并行的工作负载,C会赢,但这将是一个有趣的测试。)我想你误解了我的评论。我想看到两种不同的比较:(1)Swift N计算选项。并发并行与Swift单线程;(2)Swift N计算选项。并发并行与C OpenMP并行。w/r/t#1,我的评论站得住脚。无论使用何种API,单线程与并行都是无趣的,因为它首先应该完全由工作负载的并行性问题决定。不,我认为基准测试(1)这对于了解我们是否可以使用NSEnumerationOptions实现接近最佳的加速非常重要。Swift应用程序中的并发并行性。我完全不相信与enumerateObjectsWithOptions(NSEnumerationOptions.Concurrent)的实现相关的开销可以忽略不计,特别是如果您需要在Swift和ObjC之间架起桥梁的话。众所周知,使用C&OpenMP可以实现接近最佳的加速(例如,与单线程版本相比,使用20个内核可以获得近20倍的加速);Swift也是这样吗?也许你需要使用另一个Swift:对,使用java实现高性能,Swift-lang.org。。。。。嗯,不知道你是否意识到,对于习惯于高性能c或fortran的人来说,这个解决方案看起来有多麻烦?无法通过openmp、mpi或其他内置的高性能并行计算库认真对待swift。我将保留openmp pragmas并使用可笑的桥接头。@μολὼν、 λαβέ同时,Swift&Swift社区非常清楚,Swift并不是所有编程问题的最终解决方案。Swift与它的前身Objective-C有很多衔接,但可以说,通过将C数据类型和函数干净地导入Swift,我们在与plain-C的衔接上付出了更多的努力。在这里,理智的、预期的现实世界解决方案是用C编写性能关键的内容,将其封装在函数中,并使用Swift提供的函数。
DispatchQueue.concurrentPerform(iterations: 1000) { (index) in
     print("current: \(index)")
}
class ConcurrentCalculator<T> {

    func calc(for b: [T], _ f: (T) -> T) -> [T?] {

        let n = b.count

        var a: [T?] = Array(repeating: nil, count: n)

        DispatchQueue.concurrentPerform(iterations: n) { i in

            a[i] = f(b[i])
        }

        return a
    }
}
let myB = Array(1...100)

func myF(b: Int) -> Int {

    b * b
}

let myCalc = ConcurrentCalculator<Int>()
let myA = myCalc.calc(for: myB, myF)

print(myA)
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196, 225, 256, 289, 324, 361, 400, 441, 484, 529, 576, 625, 676, 729, 784, 841, 900, 961, 1024, 1089, 1156, 1225, 1296, 1369, 1444, 1521, 1600, 1681, 1764, 1849, 1936, 2025, 2116, 2209, 2304, 2401, 2500, 2601, 2704, 2809, 2916, 3025, 3136, 3249, 3364, 3481, 3600, 3721, 3844, 3969, 4096, 4225, 4356, 4489, 4624, 4761, 4900, 5041, 5184, 5329, 5476, 5625, 5776, 5929, 6084, 6241, 6400, 6561, 6724, 6889, 7056, 7225, 7396, 7569, 7744, 7921, 8100, 8281, 8464, 8649, 8836, 9025, 9216, 9409, 9604, 9801, 10000]