Using x86 pause instr in SpinPause
David Holmes
david.holmes at oracle.com
Thu Aug 16 17:18:03 PDT 2012
On 17/08/2012 9:51 AM, Vitaly Davidovich wrote:
> So the VM thread detects contention of some sort and enters a spin-wait;
> while it's spinning, is it doing anything at all, like re-reading some
> memory? I was assuming, judging by the name, that it simply stalls for
> some period of time before re-checking; notifying CPU of this seems
> legit. That's wrong though I take it?
If a thread spins it is because it is hoping another thread (hopefully
on-proc) will soon make the present thread able to proceed. If the
assumption is wrong then the thread falls back to blocking. Here's an
example of where SpinPause is used:
void Thread::SpinAcquire (volatile int * adr, const char * LockName) {
if (Atomic::cmpxchg (1, adr, 0) == 0) {
return ; // normal fast-path return
}
// Slow-path : We've encountered contention -- Spin/Yield/Block strategy.
TEVENT (SpinAcquire - ctx) ;
int ctr = 0 ;
int Yields = 0 ;
for (;;) {
while (*adr != 0) {
++ctr ;
if ((ctr & 0xFFF) == 0 || !os::is_MP()) {
if (Yields > 5) {
// Consider using a simple NakedSleep() instead.
// Then SpinAcquire could be called by non-JVM threads
Thread::current()->_ParkEvent->park(1) ;
} else {
os::NakedYield() ;
++Yields ;
}
} else {
SpinPause() ;
}
}
if (Atomic::cmpxchg (1, adr, 0) == 0) return ;
}
}
I really don't know whether in this context a "pause" instruction could
potentially do something useful in terms of power use etc.
David
-----
> Thanks
>
> Sent from my phone
>
> On Aug 16, 2012 7:46 PM, "David Holmes" <david.holmes at oracle.com
> <mailto:david.holmes at oracle.com>> wrote:
>
> On 17/08/2012 9:42 AM, Vitaly Davidovich wrote:
>
> Why would you not want a pause ins? I thought the point of it was to
> inform the CPU that you're busy spinning and not doing anything
> useful
> so it can make internal adjustments (e.g. scale down frequency on a
> mobile processor).
>
>
> That's not really applicable in the contexts in which this is used
> in the VM. Spins are used as a back-off strategy for contended
> actions - the fact they are contended indicate there is active work
> happening in other threads so we are not in an "idle" state.
>
> David
>
>
> Thanks
>
> Sent from my phone
>
> On Aug 16, 2012 5:22 PM, "Daniel D. Daugherty"
> <daniel.daugherty at oracle.com
> <mailto:daniel.daugherty at oracle.com>
> <mailto:daniel.daugherty at __oracle.com
> <mailto:daniel.daugherty at oracle.com>>> wrote:
>
> On Win64, SpinPause() has been "return 0" since mid-2005.
> Way back
> when Win64 code was in os_win32_amd64.cpp:
>
> SCCS/s.os_win32_amd64.cpp:
>
> D 1.9.1.1 05/07/04 03:20:45 dice 12 10 00025/00000/00334
> MRs:
> COMMENTS:
> 5030359 -- back-end synchonization improvements - adaptive
> spinning, etc
>
> When the i486 and amd64 cpu dirs were merged back in 2007,
> the code
> became like it is below (#ifdef'ed):
>
> D 1.32 07/09/17 09:11:33 sgoldman 37 35 00264/00008/00218
> MRs:
> COMMENTS:
> 5108146 Merge i486 and amd64 cpu directories.
> Macro-ized register names. Inserted amd64 specific code.
>
> Looks like on Linux-X64, the code has used the PAUSE
> instruction
> since mid-2005:
>
> D 1.3 05/07/04 03:14:09 dice 4 3 00031/00000/00353
> MRs:
> COMMENTS:
> 5030359 -- back-end synchonization improvements - adaptive
> spinning, etc
>
> We'll have to see if Dave Dice remember why he implemented
> it this way...
>
> Dan
>
>
> On 8/16/12 12:01 PM, Eric Caspole wrote:
>
> Hi everybody,
> Does anybody know the reason why SpinPause is simply
> "return 0"
> on Win64 but uses PAUSE on Linux in a .s file?
> We would like to remove PAUSE from linux too.
>
> Thanks,
> Eric
>
>
> ./src/os_cpu/windows_x86/vm/____os_windows_x86.cpp
>
> 548 extern "C" int SpinPause () {
> 549 #ifdef AMD64
> 550 return 0 ;
> 551 #else
> 552 // pause == rep:nop
> 553 // On systems that don't support pause a
> rep:nop
> 554 // is executed as a nop. The rep: prefix
> is ignored.
> 555 _asm {
> 556 pause ;
> 557 };
> 558 return 1 ;
> 559 #endif // AMD64
> 560 }
>
>
> src/os_cpu/linux_x86/vm/linux_____x86_64.s
>
> 63 .globl SpinPause
> 64 .align 16
> 65 .type SpinPause, at function
> 66 SpinPause:
> 67 rep
> 68 nop
> 69 movq $1, %rax
> 70 ret
>
>
More information about the hotspot-runtime-dev
mailing list