我有以下代码:
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
作为标准函数指令序列实现,包括堆栈操作(推送和弹出)?
通过测试Eren,在调试模式下不会出现内联。 是否可以优化并生成内联代码?
摘要:谢谢你的回答。我希望有一天clr可以通过一种机制(如MethodImplOptions.InternalCall)内联预编译代码。然后它可以消除堆栈操作并花费大部分时间检查标志和旋转等待(比nop消耗更少的cpu资源)。
答案 0 :(得分:4)
最好试试看。示例代码:
static void Main(string[] args)
{
while (true)
Thread.SpinWait(1);
}
优化的反汇编显示:
<强> 86 强>
00000000 push ebp
00000001 mov ebp,esp
00000003 mov ecx,1
00000008 call 6F11D3FE
0000000d jmp 00000003
<强> 64 强>
00000000 sub rsp,28h
00000004 mov ecx,1
00000009 call 000000005F815434
0000000e jmp 0000000000000004
00000010 add rsp,28h
00000014 ret
因此在任何一种情况下都有无内联。
也许我错过了一些东西,但我不太明白为什么你关心堆栈操作,因为旋转CPU会消耗周期(整个目的是不收益)。
答案 1 :(得分:2)
不,抖动无法内联预编译的C ++代码,只能以IL开头的托管代码。
这与SpinWait()调用完全无关。旋转等待的目的是让处理器执行代码而不是支付线程上下文切换的成本。期望 flag 将在10,000 cpu周期或更少的时间内变为 false 。 什么类代码并不重要。 CALL是执行代码的好方法。