Exposition
I have some processing I need to do over a big buffer of data.
I can represent my calculations in the form result[i] = F(SomeSubsetOf(input)) so it's really easy to do all these calculations in parallel. the problem is I'm using a little temp buffer for some of the manipulations, and i don't want to allocate one for each calculation, i want to allocate them only on a per thread basis.
The actual question
How do i define a variable to be unique only per thread. for example:
int Calculate(byte[] buffer, int resultIndex)
{
byte temp = new byte[8];
CopyStuff(buffer, resultIndex -4 , temp, 8) // please dont be pendatic about this line
DoSomeStuff(temp)l
return GetAverage(temp);
}
now I intend to run this function using Parallel.For and temp has to be unique only for every executing thread, and obviously can be recycled for every calculation the same thread executes.
What would be the simplest and most efficient way to achieve this?
You could declare temp as a property, wrapped in ThreadLocal, and then access it's value by the Value property.
See also MSDN.
I used the third parameter here:
http://msdn.microsoft.com/en-us/library/dd783299.aspx
It initializes local data for every task executing the iterations.
Related
I am currently working on a project handling multiple byte arrays. In one scenario it could happen that an array is being reinitialized multiple times in a while loop. The only reason this happens is because the application is receiving read requests, but the information received is incorrect.
I have to have a 'clean' byte array to write back to the device indicating that the information was incorrect. The device being read from has the tendency to jump into a 'loop' where it keeps sending that 'incorrect' data until it is interacted with which is not a problem per say. Just know the device spamming read requests is not a problem at this moment in time and will be dealt with in the future.
My question is this:
Are there any performance/coding issues when reinitializing an array inside a while loop for an extended period of time? 10000+ iterations for example
Code example:
byte[] array = new byte[500]
while(condition)
{
// Some work
array = new byte[500]
Thread.Sleep(100);
// Some work
}
If the array dont change you can simply clear the Array (https://learn.microsoft.com/de-de/dotnet/api/system.array.clear?view=net-5.0):
Array.Clear(array, 0, array.Length);
To save performance you can also run your function asynchronous.
I'm making a program in which one of its functions, in order to correctly create the message to be sent, keeps calling a function I have generated to add each of the parts to the array. The thing is, in C# you can't do this because the byte arrays (and if I'm not wrong, any kind of array) has a finite Length which cannot be changed.
Due to this, I thought of creating 2 byte variables. The first one would get the first to values. The second one would be created after you know the quantity of new bytes you have to add, and after this, you would delete the first variable and create it again, with the Length of the previous variable, but adding the Length of the new values, doing the same you did with the second variable. The code I've generated is:
byte[] message_mod_0 = adr_and_func;
byte[] byte_memory_adr = AddAndTypes.ToByteArray(memory_adr);
byte[] message_mod_1 = new byte[2 + byte_memory_adr.Length];
message_mod_1 = AddAndTypes.AddByteArrayToByteArray(message_mod_0, byte_memory_adr);
AddAndTypes.AddByteArrayToByteArray(message_mod_0, AddAndTypes.IntToByte(value));
byte[] CRC = Aux.CRC(message_mod_0);
AddAndTypes.AddByteArrayToByteArray(message_mod_0, CRC);
In this code, the two variables I've meant are message_mod_0 and message_mod_1. I also think of doing the deleting and redeclaring the byte_memory_adr variable that is required in order to know which is the Length of the byte array you want to add to the ouput message.
The parameters adr_and_func, memory_adr and value are given as input parameters of the function I'm making.
The question can be summed up as: is there any way to delete variables in the same scope they were created? And, in case it can be done, would there be any problem if I created a new variable with the same name after I have deleted the first one? I can't think of any reason why that could happen, but I'm pretty new to this programming language.
Also, I don't know if there is any less messy way of doing this.
This sounds like you are writing your own custom serializer.
I would recommend just using a existing library, like protobuf.net to define your messages if at all possible.
If this is not possible you can use a BinaryWriter to write your values to a Stream. If you want to keep it in memory use a MemoryStream and use .ToArray() when your done to get a array of all bytes.
As for memory, do not worry about it. Unless you have gigabyte sized messages the memory requirements should not be an issue, and the garbage collector will automatically recycle memory when it is no longer needed, and it can do this after the last usage, regardless of scope. If you have huge memory streams you might want to look at something like recyclable memory stream since this can avoid some allocation performance issues and fragmentation issues.
We have a concurrent, multithreaded program.
How would I make a sample number increase by +5 interval every time? Does Interlocked.Increment, have an overload for interval? I don't see it listed.
Microsoft Interlocked.Increment Method
// Attempt to make it increase by 5
private int NumberTest;
for (int i = 1; i <= 5; i++)
{
NumberTest= Interlocked.Increment(ref NumberTest);
}
This is another question its based off,
C# Creating global number which increase by 1
I think you want Interlocked.Add:
Adds two integers and replaces the first integer with the sum, as an atomic operation.
int num = 0;
Interlocked.Add(ref num, 5);
Console.WriteLine(num);
Adding (i.e +=) is not and cannot be an atomic operation (as you know). Unfortunately, there is no way to achieve this without enforcing a full fence, on the bright-side these are fairly optimised at a low level. However, there are several other ways you can ensure integrity though (especially since this is just an add)
The use of Interlocked.Add (The sanest solution)
Apply exclusive lock (or Moniter.Enter) outside the for loop.
AutoResetEvent to ensure threads doing task one by one (meh sigh).
Create a temp int in each thread and once finished add temp onto the sum under an exclusive lock or similar.
The use of ReaderWriterLockSlim.
Parallel.For thread based accumulation with Interlocked.Increment sum, same as 4.
I got a Task that counts the number of packets it receives from some source.
Every 250ms a timer fires up reads and outputs the count to the user. Right after i need to set the count back to 0.
My concern is that between reading and displaying the count, but BEFORE I set count=0, count has incremented in the other thread, so i end up losing counts by zeroing it out.
I am new to Threading so i have been at multiple options.
I looked into using Interlocked but as far as i know it only gives me arithmetic operations, i don't have the option to actually set the variable to value.
I was also looking into the ReaderWriterLockSlim, what i need is the most efficient / less overhead way to accomplish since there is lot of data coming across.
You want Exchange:
int currentCount = System.Threading.Interlocked.Exchange(ref count, 0)
As per the docs:
Sets a 32-bit signed integer to a specified value and returns the original value, as an atomic operation.
I have a two-dimensional array, object[,] mData
I need to retrieve the index of a specific string (key) in that object array without using a loop (e.g foreach, for).
The reason why I don't want to use a loop is because I am trying to optimize a current block of code that uses a loop which causes the process to take a long time since it is managing too much data.
Is there a way to do this?
CODE
`
object [,] mData = null;
string sKey = String.Empty;
for (int iIndex = 0; iIndex < mData.GetUpperBound(1); iIndex++)
{
if (mData[0, iIndex].Value == sKey);
{
return;
}
}
`
You will need a loop to linear search for an element. Even if there is a method that you can call to get the index (which there isn't, I don't think), there would still be a loop inside the method.
If you're worried about performance, try a binary search if the data is sorted.
I am trying to optimize a current block of code that uses a loop which causes the process to take a long time since it is managing too many data.
Loops don't neccessarily make your code run significantly slower. The core of your problem is that you have too many data. If you have that many data, then slowness is expected. What you can do is to run the time-consuming operation asynchronously so that the UI doesn't freeze.