0

I have some Thread count pCount and I have some float[] array. I want to get a pointer to the array and then based on pCount create that many threads and fill the array with data.

fixed (float* pointer = array)
{
    IntPtr fPtr = new IntPtr(pointer);

    for (int i = 0; i < pCount; i++)
    {
        Thread t = new Thread(() => ThreadMethod(fPtr, blockWidth, blockHeight, xIndex)));
        t.Start();
    }
}


private unsafe void ThreadMethod(IntPtr p, int blockWidth, int blockHeight, int startX)
{
    Random RandomGenerator = new Random();
    for (int x = startX; x < startX + blockWidth * blockHeight; x++)
    {
        ((float*)p)[x] = ((float)(RandomGenerator.NextDouble()) - 0.5f) * 2.0f;
    }
}

So if the array was 1000x1000 and I have 4 threads I want thread 1 to fill data from 0 - 250 then thread 2 from 250 - 500, thread 3 from 500 - 750 and thread 4 from 750 - 1000.

But the way I have described up there does not work. Can anyone help?

4
  • 1
    The usage of pointers and unsafe code here is wrong. Pass the array itself instead of IntPtr and index the array as usual. Commented Mar 25, 2012 at 7:55
  • You are overcomplicating things. you don't need pointers to fill an array. Commented Mar 25, 2012 at 7:57
  • 3
    Just use a Parallel.For loop. Commented Mar 25, 2012 at 7:59
  • I was using pointers because I could not get it to work by reference. Commented Mar 25, 2012 at 19:21

1 Answer 1

1

There's no need to use pointer arithmetic to access array in C#. Here's a simplified example of how it can be done:

public void ParalellizeArrayFill(int threadCount, float[] array)
{
    if (array == null || array.Length == 0)
        throw new ArgumentException("Array cannot be empty");

    if (threadCount <= 1)
        throw new ArgumentException("Thread count should be bigger than 1");

    int itemsPerThread = array.Length / threadCount;
    for (int i = 0; i < threadCount; i++)
    {
        Thread thread = new Thread( (state) => FillArray(array, i*itemsPerThread, itemsPerThread));
        thread.Start();
    }  
}

private void FillArray(float[] array, int startIndex, int count)
{
    for (int i = startIndex; i < startIndex + count; i++)
    {
        // init value
        array[i] = value; 
    }
}

There are a few caveats to be aware of. First of all, your division may not divide equally (500/3 for example), so you have to handle this case. Also, you don't have to use pointer arithmetic since array is already passed by reference and can be accessed by index.

Sign up to request clarification or add additional context in comments.

4 Comments

This is not working. The array is just empty. It never gets filled.
Could you specify how're you doing it ? I've just copy-pasted it into visual studio, added random-number value generation and it worked.
So I just copied the exact code you posted and tried to run it on an array of 20 and a thread count of 4. Something thing is going wrong that I can't seem to fix. The FillArray method will throw an exception because array[i] is out of bounds because startIndex = 20. That is not possible because only 4 threads are created and the start index should be 0, 5, 10, and 15 but somehow it gets 20. Any ideas? This is the only stuff I have changed float[] array = new float[20]; ParalellizeArrayFill(4, array); and array[i] = (float)random.NextDouble() * 10;
NVM Fixed with a Parallel.For

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.