Arrays 在Swift中并发访问数组元素
我尝试以Swift并发方式从数组(不同的数组)写入和读取,但在运行时的写入操作中出现异常。 我有Objective-C++中的并发模糊代码:Arrays 在Swift中并发访问数组元素,arrays,swift,concurrency,objective-c++,Arrays,Swift,Concurrency,Objective C++,我尝试以Swift并发方式从数组(不同的数组)写入和读取,但在运行时的写入操作中出现异常。 我有Objective-C++中的并发模糊代码: - (cpp_blur::Bitmap)blur { Bitmap result(_source); auto indexes = [[NSIndexSet alloc] initWithIndexesInRange:NSMakeRange(0, _source.size())]; int minIndex = 0; int
- (cpp_blur::Bitmap)blur {
Bitmap result(_source);
auto indexes = [[NSIndexSet alloc] initWithIndexesInRange:NSMakeRange(0, _source.size())];
int minIndex = 0;
int maxIndex = static_cast<int>(result.size()) - 1;
[indexes enumerateIndexesWithOptions:NSEnumerationConcurrent
usingBlock:[&](NSUInteger idx, BOOL* _Nonnull stop){
double sum = 0.0;
for (int i = static_cast<int>(idx) - static_cast<int>(self.radius); i <= idx + self.radius; i++) {
int index = clamp(i, minIndex, maxIndex);
sum += self->_source.at(index);
}
sum /= static_cast<double>(self.radius * 2 + 1);
result.at(idx) = sum;
}];
return result;
}
如果我在result[index]=avg
周围添加一个锁,这个异常将被移除,但我会遇到性能问题。
如何在不锁定的情况下更改Swift数组中元素的值(同时只更改不同的元素)?
这是否回答了您的问题?不,等待完成所有任务不是有问题吗。但在答案中,还添加了一个围绕书写操作的锁。我想避免锁,因为我写入不同的索引,并且有足够的内存。锁的存在是为了防止在数组中写入时出现竞速情况。不管你有没有资源,你都希望这样。考虑到
等待完成
:枚举索引选项
内置了它。无需等待,外部函数将只返回结果的初始值
。您必须等待同步写入内容。此外,所有语言中大多数集合类型的实现在写入时都不是线程安全的。您永远不应该假设它“就像在不同的线程中更改不同的变量”。除非你喜欢花几个晚上调试崩溃的并行代码。如果你特别询问Blur
:它应该在CPU
上完成。如果你问的是一般性问题:为了获得理想的性能,你必须使用缓冲区等手动管理内存。但最好看看simd
。
@objc public func blur() -> [Double] {
var result = source
let indexSet = NSIndexSet(indexesIn: NSMakeRange(0, source.count))
let from = -Int(self.blurRadius)
let to = Int(self.blurRadius)
let lastIndex = self.source.count - 1
indexSet.enumerate(options: .concurrent) { (index:Int, _) in
let sum = ((from + index)...(to + index)).reduce(0.0) { (partial:Double, nonClamped:Int) -> Double in
let index = self.clamp(nonClamped, min: 0, max: lastIndex)
let result = partial + self.source[index]
return result
}
let avg = sum / Double(2 * self.blurRadius + 1);
result[index] = avg //here I have crash in runtime
}
return result
}