首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >当Thread.SpinWait被调用时会被内联吗?

当Thread.SpinWait被调用时会被内联吗?
EN

Stack Overflow用户
提问于 2013-10-31 08:34:48
回答 2查看 237关注 0票数 2

我有以下代码:

代码语言:javascript
复制
while(flag)
{
  Thread.SpinWait(1);
}

下面是SpinWaitRotor(sscli20\clr\src\vm\comsynchronizable.cpp)中的实现

代码语言:javascript
复制
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资源)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-10-31 09:02:55

最好试着去看看。样本代码:

代码语言:javascript
复制
static void Main(string[] args)
{
    while (true) 
        Thread.SpinWait(1);
} 

优化后的拆卸结果显示:

x86:

代码语言:javascript
复制
00000000  push        ebp 
00000001  mov         ebp,esp 
00000003  mov         ecx,1 
00000008  call        6F11D3FE 
0000000d  jmp         00000003 

x64:

代码语言:javascript
复制
00000000  sub         rsp,28h 
00000004  mov         ecx,1 
00000009  call        000000005F815434 
0000000e  jmp         0000000000000004 
00000010  add         rsp,28h 
00000014  ret 

因此,在这两种情况下,都没有内联

也许我遗漏了一些东西,但我不太明白为什么您会关心堆栈操作,因为旋转CPU无论如何都会消耗周期(整个目的是不屈服)。

票数 4
EN

Stack Overflow用户

发布于 2013-10-31 09:32:35

不,抖动不能内联预编译的C++代码,只有以IL启动的托管代码。

这与SpinWait()调用完全无关。旋转等待的要点是让处理器执行代码,而不是支付线程上下文切换的成本。期望在10,000个cpu周期或更短的时间内,标志将变为false。不管是哪种代码。调用是执行代码的好方法。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19701664

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档