1

我有这段代码:

noObjs = 0
Dim oName As String
Dim i As Integer
Dim tripleIndex As Integer = 0
Do While sr.Peek() <> -1
   readCSV = sr.ReadLine.Split(sepChar(0))
   If readCSV.Length >= 3 Then
       oName = readCSV(0)
       For i = noObjs - 1 To 0 Step -1
           If oName = objNames(i) Then
               obIndOfTriple(tripleIndex) = i
               Exit For
           End If
       Next i
       If i = -1 Then
           objNames(noObjs) = oName
           obIndOfTriple(tripleIndex) = noObjs
           noObjs += 1
       End If
   End If
   tripleIndex += 1
Loop
sr.Close()

我正在尝试这样并行化:

noObjs = 0
Dim oName As String
Dim i As Integer
Dim tripleIndex As Integer = 0
Dim allData() As String = File.ReadAllLines(in_file)
Parallel.For(0, allData.Count, Sub(k)
                               readCSV = allData(k).Split(sepChar(0))
                               If readCSV.Length >= 3 Then
                                   oName = readCSV(0)
                                   For i = noObjs - 1 To 0 Step -1
                                       If oName = objNames(i) Then
                                           obIndOfTriple(tripleIndex) = i
                                           Exit For
                                       End If
                                   Next i
                                   If i = -1 Then
                                       objNames(noObjs) = oName
                                       obIndOfTriple(tripleIndex) = noObjs
                                       noObjs += 1
                                   End If
                               End If
                               tripleIndex += 1
                               End Sub)

但是,我在以下位置得到一个“索引超出了数组的范围”:

If oName = objNames(i) Then

我还应该在这里提到 objNames() 和 obIndOfTriple() 是全局声明的(具有固定大小)。通过一些搜索,我了解到这与线程安全有关,尽管我仍然是并行性的新手。谁能指出我正确的方向?谢谢。

4

2 回答 2

3

看来您正在寻找唯一的字符串。

而不是蛮力

For i = noObjs - 1 To 0 Step -1
   If oName = objNames(i) Then
   obIndOfTriple(tripleIndex) = i
Exit For

尝试

Dictionary<String,Int32> 

和 ContainsKey

字典有快速查找

这个页面有一个并行锁定的例子。但不确定它是您需要的锁类型。

于 2012-09-23T14:15:35.833 回答
1

问题的症结在于您有多个线程访问共享资源而没有同步对这些资源的访问,从而引入了竞争条件。

例如,考虑noObjs与 相关objNames。我怀疑你想noObjs总是反映实际项目的数量objNames。现在假设您有两个同时到达objNames(noObjs) = oName的线程,当时noObjs是 4 个。一个线程将写入一个值objNames(4),然后另一个线程将立即覆盖它。第一个线程还没有到达要增加的行noObjs!此外,当两个线程都执行时noObjs += 1noObjs将为 6,但您将没有任何内容存储在noObjs(5). 这不是您所看到的异常的确切情况,但它是实施脆弱性的另一个症状。

在每个线程执行的代码中,您要确保每个线程都有自己的变量空间可以使用。你可以通过拥有objNamesobjIndOfTriple成为二维数组来做到这一点。第一个维度是循环迭代,k第二个维度是该迭代的数组索引。同样,noObjs将是一个数组,并且是与循环索引关联noObjs(k)的数组中的元素数。objNamesk

从技术上讲,这应该可行,但是您需要objNames在执行之后将一堆小数组合并为一个大数组Parallel.For- 基本上完成了 map-reduce 模式的实现。

如果你确实实现了所有这些,你可能想看看性能。您正在对单行输入进行并行处理,并且从代码来看,您似乎没有为每一行做很多工作。换句话说,将它逐行并行化,实际上可能会比仅按顺序执行它时增加更多开销。如果你有 1000 行,你实际上要求同时运行 1000 个小任务,因此管理这些任务比实际执行它们要多。现在,TPL 可能会根据其认为最好的方式来决定是否真正并行执行某些操作,以减轻对性能的影响。

于 2012-09-23T02:42:34.223 回答