4

我有一个巨大的数组,两个线程正在对它进行不同的分析:

  • 数据很大 - 不允许复制
  • 线程必须同时处理
  • 必须禁用边界检查以获得最佳性能

因此,每个线程看起来像这样:

unsafe void Thread(UInt16[] data)
{
  fixed(UInt16* pData = data)
  {
    UInt16* pDataEnd = pData + data.Length;
    for(UInt16* pCur=pData; pCur != pDataEnd; pCur++)
    {
      // do stuff
    }
  }
}

由于没有互斥锁(故意),我想知道在并行线程上的相同数据上使用两个固定语句是否安全?大概第二个固定应该返回与第一个相同的指针,因为内存已经固定......当第一个完成时,它不会真正取消固定内存,因为第二个固定()仍然处于活动状态......有没有人试过这个设想?

4

3 回答 3

2

根据“CLR via C#”,这样做是安全的。

编译器在变量上设置一个“固定”标志pData(在指针上,而不是在数组实例上)。

所以多次/递归使用应该没问题。

于 2012-04-12T19:03:30.757 回答
1

也许您可以使用 GCHandle.Alloc 来固定数组,而不是使用固定的:

// not inside your thread, but were you init your shared array
GCHandle handle = GCHandle.Alloc(anArray, GCHandleType.Pinned);
IntPtr intPtr = handle.AddrOfPinnedObject();


// your thread
void Worker(IntPtr pArray)
{
  unsafe
  {
     UInt16* ptr = (UInt16*) pArray.ToPointer();
      ....
  }
}        
于 2012-04-12T19:13:30.657 回答
1

如果你需要做的只是

 for(int i = 0; i < data.Length; i++)
 {
     // do stuff with data[i]
 }

JIT 编译器消除了边界检查。所以不需要不安全的代码。

请注意,如果您的访问模式比这更复杂,则这不成立。

于 2012-04-12T19:15:20.337 回答