Question

I am calculating stock market index which changes so ofthen that I've decided to give it separate "core" (one of 24 virtual available cores) of my server (running 2 * E5-2640) cause anyway so far I have only 5% of CPU load so I have a lot of free CPU power available.

As I need asap reaction to stock market index change I've decided to use lock-free code. This is example of what I'm going to use in real life:

using System;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

namespace TestBlockingCollection2
{
    class Program
    {

        static void Main(string[] args)
        {
            Stopwatch sw = Stopwatch.StartNew();
            int i = 0;

            Task.Factory.StartNew(() =>
            {
                while (true)
                {
                    Console.WriteLine("Adding " + (i + 1));
                    sw = Stopwatch.StartNew();
                    i++;
                    Thread.Sleep(1000);
                }
            }, TaskCreationOptions.LongRunning);

            Task.Factory.StartNew(() =>
                                      {
                int prevI = 0;
                while (true)
                {
                    if (prevI < i)
                    {
                        sw.Stop();
                        long microseconds = sw.ElapsedTicks / (Stopwatch.Frequency / (1000L * 1000L));
                        Console.WriteLine("Received " + i + ". Spent " + microseconds + " microseconds.");
                        prevI = i;
                    }
                }
            }, TaskCreationOptions.LongRunning);

            while (true)
            {
                Thread.Sleep(1000);
            }
        }
    }
}

Output:

C:\bin\testBlockingCollection2>TestBlockingCollection2.exe
Adding 1
Received 1. Spent 1 microseconds.
Adding 2
Received 2. Spent 5 microseconds.
Adding 3
Received 3. Spent 2 microseconds.
Adding 4
Received 4. Spent 2 microseconds.
Adding 5
Received 5. Spent 2 microseconds.
Adding 6
Received 6. Spent 4 microseconds.
Adding 7
Received 7. Spent 2 microseconds.
Adding 8
Received 8. Spent 2 microseconds.
Adding 9
Received 9. Spent 5 microseconds.
Adding 10
Received 10. Spent 2 microseconds.
Adding 11
Received 11. Spent 2 microseconds.
Adding 12
Received 12. Spent 2 microseconds.
Adding 13
Received 13. Spent 2 microseconds.
Adding 14
Received 14. Spent 2 microseconds.
Adding 15
Received 15. Spent 2 microseconds.
Adding 16
Received 16. Spent 3 microseconds.
Adding 17
Received 17. Spent 5 microseconds.
Adding 18
Received 18. Spent 2 microseconds.
Adding 19
Received 19. Spent 2 microseconds.

Having 2 microseconds in average is pretty amazing comparing to 18 microseconds that I have using BlockingCollection what better do we have to asynchronous execute method than BlockingCollection?

And I really want this microseconds as I have a lot of free CPU power and in HFT microseconds are important.

So the question is easy - do you see any problems with my example? I was not ever wrote lock-free code so I guess I may do stupid mistakes. I do not use spinlocks, as I assume primitive change (int/double/decimal) is "atomic" and so in the second thread I always receive either previous or new value but nothing else.

I.e. if in one thread I'm changing int x from 100 to 555, in second thread I will either have 100 or 555, but never 500 or 155 or anything else.

No correct solution

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top