Using Grand Central Dispatch in Swift to parallelize and speed up for loops?

I'm trying to bow my head around how to use the GCD to parallelize and speed up Monte Carlo simulations. Most / all simple examples are provided for Objective-C, and I really need a simple example for Swift, since Swift is my first β€œreal” programming language.

The smallest working version of Monte Carlo simulation in Swift will be something like this:

import Foundation import Cocoa var winner = 0 var j = 0 var i = 0 var chance = 0 var points = 0 for 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) 

The code works directly inserted into the project of the command line program in xcode 6.1

The innermost loop cannot be parallelized because the new value of the point variable is used in the next loop. But the outermost ones just run the innermost simulation 1,000,000 times and count the results and should be the perfect candidate for parallelization.

So my question is how to use GCD to parallelize the outermost loop?

+5
source share
1 answer

Multithreaded iteration can be done using dispatch_apply() :

 let outerCount = 100 // # of concurrent block iterations let innerCount = 10000 // # of iterations within each block let 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 { // ... } } 

(You should find the best balance between external and internal calculations.)

Two things can be noticed:

Then it will be something like this:

 let outerCount = 100 // # of concurrent block iterations let innerCount = 10000 // # of iterations within each block let 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, 0, +) println(winner) 
+5
source

Source: https://habr.com/ru/post/1207592/


All Articles