我编写了小型测试程序,但感到惊讶的是,为什么lock {}解决方案的性能要比无锁更快,但在静态变量上具有[ThreadStatic]属性。

[ThreadStatic]代码段:

[ThreadStatic]
private static long ms_Acc;
public static void RunTest()
{
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();
    int one = 1;
    for (int i = 0; i < 100 * 1000 * 1000; ++i) {
        ms_Acc += one;
        ms_Acc /= one;
    }
    stopwatch.Stop();
    Console.WriteLine("Time taken: {0}", stopwatch.Elapsed.TotalSeconds);
}

锁定{}片段:
private static long ms_Acc;
private static object ms_Lock = new object();
public static void RunTest()
{
    Stopwatch stopwatch = new Stopwatch();
    stopwatch.Start();
    int one = 1;
    for (int i = 0; i < 100 * 1000 * 1000; ++i) {
        lock (ms_Lock) {
            ms_Acc += one;
            ms_Acc /= one;
        }
    }
    stopwatch.Stop();
    Console.WriteLine("Time taken: {0}", stopwatch.Elapsed.TotalSeconds);
}

在我的计算机上,第一个代码段需要4.2秒;秒-3.2秒,快1秒。没有ThreadStatic和锁定-1.2秒。

我很好奇,为什么这个简单示例中的[ThreadStatic]属性会增加程序执行时间?

更新:非常抱歉,但是这些结果适用于DEBUG构建。对于RELEASE,我得到了完全不同的数字:(1.2; 2.4; 1.2)。对于DEBUG,数字为(4.2; 3.2; 1.2)。

因此,对于RELEASE构建,似乎没有[ThreadStatic]性能损失。

最佳答案

对于RELEASE构建,似乎几乎没有[ThreadStatic]性能损失(在现代CPU上只有很小的损失)。

这是ms_Acc += one的反汇编代码;启用RELEASE优化:

没有 [ThreadStatic]DEBUG:

00000060  mov         eax,dword ptr [ebp-40h]
00000063  add         dword ptr ds:[00511718h],eax

没有 [ThreadStatic]RELEASE:
00000051  mov         eax,dword ptr [00040750h]
00000057  add         eax,dword ptr [rsp+20h]
0000005b  mov         dword ptr [00040750h],eax
[ThreadStatic]DEBUG:
00000066  mov         edx,1
0000006b  mov         ecx,4616E0h
00000070  call        664F7450
00000075  mov         edx,1
0000007a  mov         ecx,4616E0h
0000007f  mov         dword ptr [ebp-50h],eax
00000082  call        664F7450
00000087  mov         edx,dword ptr [eax+18h]
0000008a  add         edx,dword ptr [ebp-40h]
0000008d  mov         eax,dword ptr [ebp-50h]
00000090  mov         dword ptr [eax+18h],edx
[ThreadStatic]RELEASE:
00000058  mov         edx,1
0000005d  mov         rcx,7FF001A3F28h
00000067  call        FFFFFFFFF6F9F740
0000006c  mov         qword ptr [rsp+30h],rax
00000071  mov         rbx,qword ptr [rsp+30h]
00000076  mov         ebx,dword ptr [rbx+20h]
00000079  add         ebx,dword ptr [rsp+20h]
0000007d  mov         edx,1
00000082  mov         rcx,7FF001A3F28h
0000008c  call        FFFFFFFFF6F9F740
00000091  mov         qword ptr [rsp+38h],rax
00000096  mov         rax,qword ptr [rsp+38h]
0000009b  mov         dword ptr [rax+20h],ebx

关于c# - .NET : ThreadStatic vs lock { }.为什么ThreadStaticAttribute会降低性能?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7131723/

10-12 00:42