Mam dużą tablicę, którą chciałbym przetworzyć, przekazując plasterki do kilku asynchronicznych zadań. Jako dowód koncepcji, mam napisane następujący kod:Array procesowy równolegle za pomocą GCD
class TestParallelArrayProcessing {
let array: [Int]
var summary: [Int]
init() {
array = Array<Int>(count: 500000, repeatedValue: 0)
for i in 0 ..< 500000 {
array[i] = Int(arc4random_uniform(10))
}
summary = Array<Int>(count: 10, repeatedValue: 0)
}
func calcSummary() {
let group = dispatch_group_create()
let queue = dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0)
for i in 0 ..< 10 {
dispatch_group_async(group, queue, {
let base = i * 50000
for x in base ..< base + 50000 {
self.summary[i] += self.array[x]
}
})
}
dispatch_group_notify(group, queue, {
println(self.summary)
})
}
}
Po init()
, array
zostanie zainicjowany z losowych liczb całkowitych od 0 do 9.
Funkcja calcSummary
wywołuje 10 zadań, które mają rozłączne fragmenty z 50000 pozycji z array
i dodaj je, używając odpowiedniego gniazda w summary
jako pulsatora.
Ten program zawiesza się na linii self.summary[i] += self.array[x]
. Błąd jest:
EXC_BAD_INSTRUCTION (code = EXC_I386_INVOP).
widzę w debugger, że udało się iteracji kilka razy przed upaść, i że zmienne, w momencie katastrofy, mają wartości w prawidłowych granicach.
Przeczytałem, że EXC_I386_INVOP
może się zdarzyć podczas próby uzyskania dostępu do obiektu, który został już zwolniony. Zastanawiam się, czy ma to coś wspólnego z tym, że Swift tworzy kopię tablicy, jeśli jest zmodyfikowana, a jeśli tak, to jak tego uniknąć.
Dzięki. Zastanawiam się, czy to naprawdę działa, czy też jest przypadkiem, ponieważ istnieje tylko dziesięć zadań (mój oryginalny kod jest w stanie powtórzyć kilka razy przed awarią). Spróbuję z większą tablicą 'summary' i zobaczę co się stanie. – Eduardo
Interesujące ... na podstawie Twojego kodu, zwiększyłem liczbę zadań do 100 i nadal działa. Mój problem polega na tym, że napisany przeze mnie kod jest uproszczeniem tego, czego potrzebuję i naprawdę muszę zgromadzić je w "streszczeniu". Spróbuję rozwiązać to bezpośrednio pisząc do pamięci. – Eduardo
Praca z pamięcią 'summary' wydaje się rozwiązać problem. Naprawdę brakuje mi możliwości przekazywania tablic przez odniesienie! – Eduardo