Swap should be better done native?

Ulf Zibis Ulf.Zibis at gmx.de
Fri Apr 2 16:56:22 PDT 2010


Am 02.04.2010 20:42, schrieb Martin Buchholz:
> On Thu, Apr 1, 2010 at 16:17, Ulf Zibis<Ulf.Zibis at gmx.de>  wrote:
>    
>> Am 01.04.2010 23:55, schrieb Martin Buchholz:
>>      
>>> On Thu, Apr 1, 2010 at 05:32, Ulf Zibis<Ulf.Zibis at gmx.de>    wrote:
>>>
>>>
>>>        
>>>>> How can 4 put(byte) be converted into one put(int)?
>>>>>
>>>>>
>>>>>            
>>>> See the following code snippets ...
>>>>
>>>> ===================================================
>>>> Codesnippet from EUC_TW$Encoder:
>>>>             dst.put(SS2);
>>>>             dst.put((byte)(0xa0 | p));
>>>>             dst.put((byte)(db>>    8));
>>>>             dst.put((byte)db);
>>>>
>>>>          
>>>
>>>        
>>>> ===================================================
>>>> Alternative 1 codesnippet:
>>>>             dst.putInt((SS2<<    24) | (0xa0<<    16) | (p<<    16) | db);
>>>>
>>>>          
>>> Ahhh, I see.  Direct buffers are optimized to use Unsafe.putInt
>>> on platforms where unaligned writes are possible (i.e. x86).
>>>
>>> Some problems with that:
>>>        
>    
>>> - this only works on x86
>>>
>>>        
>> Correct me if I'm wrong: On all platforms 4 put(byte) can be converted into
>> one put(int), but the performance win would be different.
>>      
> No.  In general, we can't assume that the target address is int-aligned,
> and non-x86 architectures require alignment for word writes to memory.
>    

This should be a rare case even on non-x86 architectures.
It generally should only happen, if the offset of a sliced buffer is not 
aligned to it's value size.
Fresh allocated buffers should be always properly aligned (hopefully).

I wanted to say, that 4 put(byte) can be replaced by one put(int), but 
would perform likely worse in the rare case of unaligned position pointer.
E.g. this can happen frequently on UTF-8 coder, but could always be checked.

>    
>> Maybe using put(byte[]) would be better on other platforms ?
>>      
> But then you'd have to allocate an expensive byte array,
> and write to it first?
>    

This should not be expensive, if byte[] would be reused on same coder 
instance and -XX:+DoEscapeAnalysis is set or would become default in the 
future. See:
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6908239

>    
>>> - this doesn't work with other subclasses of ByteBuffer
>>>
>>>        
>> Not sure, if I understand right. Which subclasses you mean? CharBuffer,
>> e.g., is NOT subclass of ByteBuffer.
>> But I see an advantage to have putInt/Long in Char/Short/IntegerBuffer.
>>
>>      
>>> - I would think optimizing the case of ByteBuffer with arrays
>>>    (ie. hasArray() is true) would be more important.
>>>
>>>        
>> I don't think, optimizing the case for the direct buffers would harm the
>> case for the heap buffers.
>>      
> charsets have two cases - general Buffer implementation,
> and a specialized one if hasArray() is true for both Buffers.
> So switching to putInt instead of putByte
> might slow things down either on non-x86

Therefore, as you have just suggested, heap buffers should be refactored 
to use unsafe char/short/int/long transfer on x86 architectures or if 
position pointer is properly aligned.
BTW, my suggestion to use putChar(char)/put(byte[]) was only meant for 
direct buffer case in UTF_8$Encoder, respectively 
getChar(char)/get(byte[])  for UTF_8$Decoder.
Looking in the disassembles I additionally believe, HotSpot could better 
optimize both cases, e.g. a previewing bounds check in case of 
consecutive bytes accessed or a more economical reuse of the arrays 
oop/content pointers.

>   or if
> transferring between direct buffer and heap buffer.
>    

Therefore I've implemented 4 cases in my SingleByteXcoder:
https://java-nio-charset-enhanced.dev.java.net/source/browse/java-nio-charset-enhanced/trunk/src/sun/nio/cs/SingleByteDecoder_new.java?rev=&view=markup
https://java-nio-charset-enhanced.dev.java.net/source/browse/java-nio-charset-enhanced/trunk/src/sun/nio/cs/SingleByteEncoder_new.java?rev=&view=markup

-Ulf




More information about the nio-dev mailing list