You are viewing a plain text version of this content. The canonical link for it is here.
Posted to users@tomcat.apache.org by "Caldarale, Charles R" <Ch...@unisys.com> on 2006/03/14 16:10:55 UTC
RE: [OT] Performance tricks with multiple tomcat instances
> From: Darryl L. Miles [mailto:darryl@netbauds.net]
> Subject: Re: Performance tricks with multiple tomcat instances
>
> I would hope that JIT compiler engineers would as a minimum
> implicitly add the "lock" instruction before all operations
> on primitive types declared volatile that are in the platforms
> native data width (32bit on i386, 32&64bit on i386_64. 64bit
> on ia64).
Not done, since the Java/JVM specs don't require atomic operations
except for assignments. If you want to insure that an increment is
atomic, you must surround it with a synchronized block.
Volatile does not imply atomic. Please read the specs.
> So maybe the JVM specification should also adopt a new
> keyword for a specific atomic integer data type and another
> one to mark those accesses to that it must be atomic.
Very unlikely to happen, since the synchronized block covers the
required semantics. Modern implementations of synchronized are very
fast.
> so if you want to write out a 64bit value you have to make
> two memory write cycles and this is done with two assembler
> instructions, the i386 processor does not provide any
> hardware support to make that atomic, so you have to make
> that synchronization / lock happen in software there is no
> 2 ways about this).
Actually, that's not true anymore. Most newer chips have a 64-bit data
path, and properly aligned 64-bit loads/stores are implicitly atomic -
but there's no guarantee. There's also a compare-and-exchange-8-bytes
in the current IA32 instruction set, and that can be made atomic with
the lock prefix.
> What is not said is that having atomic assignment is
> not useful on its own
Sorry, but atomic assignment is absolutely critical. Without it, all
pointer updates and retrievals would have to be done under storage lock
- and that would be prohibitively expensive.
> single operations are implicitly atomic
Only when properly aligned and supported by the memory system. Since
the lowest common denominator of memory access these days is a byte, you
cannot assume that anything larger is atomic without reference to the
specs for the platform you happen to be running on. (And there are a
lot of platforms that are not IA32 - what's in your cell phone?)
> A nice clean way to do this in java would be a with
> class/method that the JIT would replace with optimized
> versions, this would keep keyword pollution down that my
> naive example above incites.
Already done - see the java.util.concurrent.atomic package in JRE 5.
- Chuck
THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY
MATERIAL and is thus for use only by the intended recipient. If you
received this in error, please contact the sender and delete the e-mail
and its attachments from all computers.
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org
Re: [OT] Performance tricks with multiple tomcat instances
Posted by "Darryl L. Miles" <da...@netbauds.net>.
Caldarale, Charles R wrote:
>> From: Darryl L. Miles [mailto:darryl@netbauds.net]
>> Subject: Re: Performance tricks with multiple tomcat instances
>>
>> I would hope that JIT compiler engineers would as a minimum
>> implicitly add the "lock" instruction before all operations
>> on primitive types declared volatile that are in the platforms
>> native data width (32bit on i386, 32&64bit on i386_64. 64bit
>> on ia64).
>>
>
> Not done, since the Java/JVM specs don't require atomic operations
> except for assignments. If you want to insure that an increment is
> atomic, you must surround it with a synchronized block.
>
> Volatile does not imply atomic. Please read the specs.
>
I've never used volatile in any java code I've written. So its a
non-issue for me.
But the point being made by me was food for thought. I had read some
comments that might lead others to think that "count++" on a java "int"
type is in some way atomic. I was pointing out that even the assembler
instruction to increment a memory operand is not atomic (in the case of
multi CPU SMP systems) unless special care was taken to use the provided
"lock" instruction on the sub-set of x86 assembly that allows it. I've
also read others comments that using the java "volatile" keyword was
some way out of their sticky situation; then in order for that to be
true and be a portable performance locking primitive across JVMs on
different target hosts it would need to restrict the allowed bit width
to java "int" or "long" since thats all some CPU will give you. A
recent related issue in TC
http://issues.apache.org/bugzilla/show_bug.cgi?id=37356
If in doubt just synchronize, then if there is a real performance hit
fix your application design to work around the new problem.
>> so if you want to write out a 64bit value you have to make
>> two memory write cycles and this is done with two assembler
>> instructions, the i386 processor does not provide any
>> hardware support to make that atomic, so you have to make
>> that synchronization / lock happen in software there is no
>> 2 ways about this).
>>
>
> Actually, that's not true anymore. Most newer chips have a 64-bit data
> path, and properly aligned 64-bit loads/stores are implicitly atomic -
> but there's no guarantee. There's also a compare-and-exchange-8-bytes
> in the current IA32 instruction set, and that can be made atomic with
> the lock prefix.
>
You miss the goal of programming to the lowest common denominator with
your point, write once run anywhere is something of value to me, if this
means I have to synchronize everything thats fine by me. If some CPU
has 64bit paths and the JVM has support that is a good thing, a new set
of classes should be introduced to give access to that additional
functionality so those users who would find those features useful to
them have access.
But in most cases just a portable single 32bit or 64bit integer type for
this purpose will do the trick most of the time than having a feature
full API that works with many types is unnecessary. The goal is to
provide the application programmer with an API contract that works
across a wide range of JVM implementations and CPUs.
I don't understand your contradiction "are implicitly atomic - but
there's no guarantee" if there is no guarantee then by my book it is not
atomic.
>
>> What is not said is that having atomic assignment is
>> not useful on its own
>>
>
> Sorry, but atomic assignment is absolutely critical. Without it, all
> pointer updates and retrievals would have to be done under storage lock
> - and that would be prohibitively expensive.
>
But atomic assignment is like saying the grass is green and the sky is
blue. There is no useful point to make here, it is a given that memory
load/store operations using native bit width operations on any CPU are
atomic, you are either loading or storing not both. Its only when you
start talking about read-modify-write operations that the word atomic
carries any significant meaning.
So yes in the computing world atomic assignment is absolutely critical
but so is register addition.
>
>> single operations are implicitly atomic
>>
>
> Only when properly aligned and supported by the memory system. Since
> the lowest common denominator of memory access these days is a byte, you
> cannot assume that anything larger is atomic without reference to the
> specs for the platform you happen to be running on. (And there are a
> lot of platforms that are not IA32 - what's in your cell phone?)
>
Are you saying that there are some CPUs that support unaligned access to
memory (like x86) that do not have atomic writes to memory. Please cite
references to this point it interests me greatly.
I was under the impression that such accesses by the CPU to the memory
bus were atomic, because the CPU acquired the memory bus, then did one
or more writes in burst before releasing the memory bus. No other CPU
can get in under this access. So even unaligned load or store is atomic.
Your reply above implies there are some extra conditions that must be
met as well (access alignment and memory bus path size), I disagree with
your point here.
Generally most access is aligned to help performance on any platform and
those systems that dont allow unaligned access dont have the problem as
they force you to align.
In principal the same process is how the LOCK instruction works on x86,
in the increment with memory operand case the CPU:
* Loads the current value from memory to an anonymous CPU register
(phase 1 - read)
* The CPU increments the value in the anonymous register (phase 2 - modify)
* The CPU then Stores the new value back to the same memory location
(phase 3 - write)
The LOCK instruction makes the CPU maintain its memory bus acquisition
during phase 2. Without the LOCK instruction the CPU will release it
and that would allow a window for another CPU to access memory. This is
where multi CPU SMP comes into play going back to Leon's findings. A
kernel can not task switch an assembly instruction so under single CPU
the read-modify-write (with or without the LOCK) is always 100%
successful so you will never seem a problem existed, even with a
multi-threaded application, but when you add another CPU under SMP into
the mix the use of the LOCK prefix become important.
Sorry if this is sucking eggs here.
>
>> A nice clean way to do this in java would be a with
>> class/method that the JIT would replace with optimized
>> versions, this would keep keyword pollution down that my
>> naive example above incites.
>>
>
> Already done - see the java.util.concurrent.atomic package in JRE 5.
>
Thanks for this pointer, I will go and look some more at this with a
view of introducing it into project that are JRE 5 based.
FYI - The Sun documention that headlines the package talks in terms of
"volatile" values. LOL
--
Darryl L. Miles
---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org
For additional commands, e-mail: users-help@tomcat.apache.org