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