macos – 在Swift中使用Grand Central Dispatch来并行化并加速“for”循环?

macos – 在Swift中使用Grand Central Dispatch来并行化并加速“for”循环?,第1张

概述我试图围绕如何使用GCD来并行化和加速蒙特卡罗模拟.大部分/全部简单示例都是针对Objective C提供的,我真的需要一个Swift的简单示例,因为Swift是我的第一个“真正的”编程语言. Swift中蒙特卡罗模拟的最小工作版本将是这样的: import Foundationimport Cocoavar winner = 0var j = 0var i = 0var chance 我试图围绕如何使用GCD来并行化和加速蒙特卡罗模拟.大部分/全部简单示例都是针对Objective C提供的,我真的需要一个Swift的简单示例,因为Swift是我的第一个“真正的”编程语言.

Swift中蒙特卡罗模拟的最小工作版本将是这样的:

import Foundationimport Cocoavar winner = 0var j = 0var i = 0var chance = 0var points = 0for j=1;j<1000001;++j{    var ability = 500    var player1points = 0    for i=1;i<1000;++i{        chance = Int(arc4random_uniform(1001))        if chance<(ability-points) {++points}        else{points = points - 1}    }    if points > 0{++winner}}    println(winner)

代码可以直接粘贴到xcode 6.1中的命令行程序项目中

最内层的循环不能并行化,因为变量“points”的新值在下一个循环中使用.但最外面的只是运行最里面的模拟1000000次并计算结果,应该是并行化的理想候选者.

所以我的问题是如何使用GCD并行化最外层的for循环?

可以使用dispatch_apply()完成“多线程迭代”:
let outerCount = 100    // # of concurrent block iterationslet innerCount = 10000  // # of iterations within each blocklet the_queue = dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_DEFAulT,0);dispatch_apply(UInt(outerCount),the_queue) { outerIDx -> VoID in    for innerIDx in 1 ... innerCount {       // ...    }}

(你必须弄清楚外部和内部计数之间的最佳关系.)

有两件事需要注意:

> arc4random()使用内部互斥锁,这使得它在调用时非常慢
从几个并行的线程,见Performance of concurrent code using dispatch_group_async is MUCH slower than single-threaded version.从那里给出的答案,
rand_r()(每个线程都有单独的种子)似乎是更快的选择.
>不得同时从多个线程修改结果变量获胜者.
您可以使用数组,而不是每个线程更新其自己的元素和结果
之后加入.在https://stackoverflow.com/a/26790019/1187415中描述了线程安全的方法.

然后它大致如下:

let outerCount = 100     // # of concurrent block iterationslet innerCount = 10000   // # of iterations within each blocklet the_queue = dispatch_get_global_queue(disPATCH_QUEUE_PRIORITY_DEFAulT,0);var winners = [Int](count: outerCount,repeatedValue: 0)winners.withUnsafeMutableBufferPointer { winnersPtr -> VoID in    dispatch_apply(UInt(outerCount),the_queue) { outerIDx -> VoID in        var seed = arc4random() // seed for rand_r() in this "thread"        for innerIDx in 1 ... innerCount {            var points = 0            var ability = 500            for i in 1 ... 1000 {                let chance = Int(rand_r(&seed) % 1001)                if chance < (ability-points) { ++points }                else {points = points - 1}            }            if points > 0 {                winnersPtr[Int(outerIDx)] += 1            }        }    }}// Add results:let winner = reduce(winners,+)println(winner)
总结

以上是内存溢出为你收集整理的macos – 在Swift中使用Grand Central Dispatch来并行化并加速“for”循环?全部内容,希望文章能够帮你解决macos – 在Swift中使用Grand Central Dispatch来并行化并加速“for”循环?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1051316.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-25
下一篇2022-05-25

发表评论

登录后才能评论

评论列表(0条)

    保存