1

我正在计算经常变化的股票市场指数,所以我决定给我的服务器(运行 2 * E5-2640)单独的“核心”(24 个虚拟可用核心之一),因为到目前为止我只有 5% CPU 负载,所以我有很多可用的空闲 CPU 电源。

由于我需要尽快对股市指数变化做出反应,我决定使用无锁代码。这是我将在现实生活中使用的示例:

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);
            }
        }
    }
}

输出:

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.

与我使用BlockingCollection 异步执行方法比 BlockingCollection 更好的 18 微秒相比,平均有 2 微秒是相当惊人的?

我真的很想要这个微秒,因为我有很多空闲的 CPU 能力,而且在 HFT 中微秒很重要。

所以这个问题很简单——你看到我的例子有什么问题吗?我从来没有写过无锁代码,所以我想我可能会犯愚蠢的错误。我不使用自旋锁,因为我假设原始更改(int/double/decimal)是“原子的”,所以在第二个线程中,我总是收到以前的或新的值,但没有别的。

即,如果在一个线程中我将 int x 从 100 更改为 555,那么在第二个线程中我将拥有 100 或 555,但绝不会是 500 或 155 或其他任何值。

4

0 回答 0