harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tim Ellison <t.p.elli...@gmail.com>
Subject Re: [jira] Created: (HARMONY-6328) [classlib][nio] optimize SocketChannel.write(ByteBuffer[], int, int) by writev
Date Mon, 07 Sep 2009 09:06:03 GMT
On 07/Sep/2009 09:33, Regis wrote:
> Tim Ellison wrote:
>> On 03/Sep/2009 12:29, Regis wrote:
>>> Tim Ellison wrote:
>>>> A minor comment first :-) Please check return values for :
>>>>
>>>> + vect = (struct iovec*) hymem_allocate_memory(sizeof(struct iovec) *
>>>> length);
>>>> +
>>>> + message = (*env)->GetPrimitiveArrayCritical(env, addrs,
>>>> &isCopyMessage);
>>>> + cts = (*env)->GetPrimitiveArrayCritical(env, counts, &isCopyCts);
>>> Yes, will add it, thanks.
>>>
>>>>
>>>> A further enhancement is to have two versions of primitives, one that
>>>> deals with direct buffers and one that deals with java heap buffers, so
>>>> that there is (potentially) no data copying required for the java-heap
>>>> buffers version that you have got today:
>>> One case stop me to do that is a buffer array contains direct and java
>>> heap buffers both. In this case, either copying java heap buffres to
>>> direct buffers or passing the whole array to native directly.
>>
>> Yes, good point.
>>
>>> If pass the array to native directly, it need to call isDirect and
>>> AddressUtil.getDirectBufferAddress in native code, as I understand, call
>>> java methods from native side is like reflection, even more expensive,
>>> so I chose copying all java heap buffers to direct buffers, at least it
>>> fast when most buffers are direct and size of java heap buffers are not
>>> too big.
>>
>> No need to use call back into Java code to do this, there are already
>> JNI functions you can use:
>>
>> jboolean IsInstanceOf(JNIEnv *env, jobject obj, jclass clazz);
>> void* GetDirectBufferAddress(JNIEnv* env, jobject buf);
>>
>> See the spec at
>> http://java.sun.com/j2se/1.5.0/docs/guide/jni/spec/functions.html
>>
>> However, you cannot always get the backing array from a ByteBuffer, so
>> you still have three cases to deal with:
>>  1. the direct byte buffer (by address)
>>  2. the heap byte buffer with backing array (may be pinned/copied)
>>  3. the heap byte buffer without an array (must be copied)
>>
>> For case (3) likely it is best to copy into a direct byte buffer to
>> ensure it does not get copied again, so you end up passing only types
>> (1) and (2) into the native.
>>
>>> One possible solution I can think is adding a new native call
>>>
>>> writevDirect(JNIEnv *env, jobject thiz, jobject fd, jobject bufferArray,
>>> jobject addrs, jobject counts, jint length)
>>>
>>> passing buffer array and native addresses of direct buffers together, if
>>> element of addrs is 0, the corresponding buffer is not direct. Well,
>>> this method is a little bit hard to understand, it has 7 parameters....
>>
>> I agree.  Maybe the best way is to pass them in as jobjects and let the
>> native code sort out the direct / heap buffers -- using the address
>> directly and getting access to the bytes respectively.
>>
> 
> I managed to implement in this way and submit a patch to JIRA.
> 
> I tried to pass a object array, if it's direct buffer, fill the array
> element with buffer directly (heap byte buffer without an array will be
> copied to direct buffer first), otherwise, pass byte array. Because we
> still need to know the offset of arrays, so I have to pass it to native
> code.
> 
> More test cases and documents are coming...

Wow, quick work!  I'll take a look.

Regards,
Tim



Mime
View raw message