我有以下代码:
while(flag)
{
Thread.SpinWait(1);
}下面是SpinWait在Rotor(sscli20\clr\src\vm\comsynchronizable.cpp)中的实现
FCIMPL1(void, ThreadNative::SpinWait, int iterations)
{
WRAPPER_CONTRACT;
STATIC_CONTRACT_SO_TOLERANT;
for(int i = 0; i < iterations; i++)
YieldProcessor();
}
FCIMPLEND当Thread.SpinWait被调用时会被内联吗?
如果不是,则在每个循环周期中,它将花费更多的时间在stack operations(push and pop) 上,并消耗更多的CPU.执行资源。
如果是,则clr ThreadNative::SpinWait 是如何实现的,而ThreadNative::SpinWait是作为标准函数指令序列实现的,包括堆栈操作(push和pop)?。
通过对Eren的测试,在调试模式下不会发生内联。可以优化和生成内联代码吗?
摘要:谢谢你的回答。我希望有一天clr可以通过一种机制(如MethodImplOptions.InternalCall )内联预编译代码。然后,它可以消除堆栈操作,并将大部分时间用于检查标志和旋转等待(比nop消耗更少的cpu资源)。
发布于 2013-10-31 09:02:55
最好试着去看看。样本代码:
static void Main(string[] args)
{
while (true)
Thread.SpinWait(1);
} 优化后的拆卸结果显示:
x86:
00000000 push ebp
00000001 mov ebp,esp
00000003 mov ecx,1
00000008 call 6F11D3FE
0000000d jmp 00000003 x64:
00000000 sub rsp,28h
00000004 mov ecx,1
00000009 call 000000005F815434
0000000e jmp 0000000000000004
00000010 add rsp,28h
00000014 ret 因此,在这两种情况下,都没有内联。
也许我遗漏了一些东西,但我不太明白为什么您会关心堆栈操作,因为旋转CPU无论如何都会消耗周期(整个目的是不屈服)。
发布于 2013-10-31 09:32:35
不,抖动不能内联预编译的C++代码,只有以IL启动的托管代码。
这与SpinWait()调用完全无关。旋转等待的要点是让处理器执行代码,而不是支付线程上下文切换的成本。期望在10,000个cpu周期或更短的时间内,标志将变为false。不管是哪种代码。调用是执行代码的好方法。
https://stackoverflow.com/questions/19701664
复制相似问题