Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

a question about mspc buffer array index #390

Open
qiugongkai opened this issue Mar 13, 2024 · 2 comments
Open

a question about mspc buffer array index #390

qiugongkai opened this issue Mar 13, 2024 · 2 comments

Comments

@qiugongkai
Copy link

i has a question about offset compute.
the jctools compute code is:
/**
* This method assumes index is actually (index << 1) because lower bit is
* used for resize. This is compensated for by reducing the element shift.
* The computation is constant folded, so there's no cost.
*/
public static long modifiedCalcCircularRefElementOffset(long index, long mask)
{
return REF_ARRAY_BASE + ((index & mask) << (REF_ELEMENT_SHIFT - 1));
}

REF_ARRAY_BASE is the array base address in memeory from JVM。

i know that the function is to compute zhe address in jvm for a array with index and mask.

but i find the index is not item in array index .
my question is the function input param index :
what the param means? it is double to array index?

@ceragon
Copy link

ceragon commented Mar 14, 2024

Your source code seems to be copied from LinkedArrayQueueUtil.

To answer this method and the meaning of its parameters, it's necessary to understand the layout of an Object[] object in the JVM heap:

  • Array header: consists of a mark word, a class pointer, and an array size. It occupies 16 bytes when the 64-bit JVM is running with compressed pointers enabled and 24 bytes otherwise.
  • Array elements: Since Java objects are references, the elements of an Object[] store references to objects. With compressed pointers enabled on a 64-bit JVM, each element occupies 4 bytes, otherwise 8 bytes.
  • Calculating the relative offset of array elements within the data object: Taking the example of a 64-bit JVM with compressed pointers enabled, the offset of element 0 is 16 + (0 * 4) = 16, the offset of element 1 is 16 + (1 * 4) = 20, and so on. In summary, it's calculated as [object header] + ([index] * [element size]) = relative offset of the element.
  • Multiplying a number by 4 can be equivalently expressed as number << 2. Similarly, multiplying by 8 can be expressed as number << 3. Therefore, calculating relative offsets can also use [object header] + ([index] << [number of bits corresponding to the element size]).

Next, let's answer the meaning of the parameter index:

  • index consists of two parts: the index of the element in the array (arrayIndex) and a flag indicating whether resizing is in progress (0: normal, 1: resizing).
  • Since the flag occupies 1 bit, index >> 1 yields the actual value of arrayIndex. Following the method of calculating relative offsets described earlier, we can obtain the offset of the element by REF_ARRAY_BASE + ((index >> 1) << REF_ELEMENT_SHIFT).
  • However, to avoid an additional shift operation, the code author modified it to REF_ARRAY_BASE + ((index & mask) << (REF_ELEMENT_SHIFT - 1)). The result of this calculation is equivalent to the previous method.

Regarding whether index is doubled:

Yes, due to the presence of the trailing flag bit, index defaults to twice the value of arrayIndex. You can find more details in the assignment operation of ConsumerIndex in BaseMpscLinkedArrayQueue.

@qiugongkai
Copy link
Author

hank you very much for your kind words. I'm glad to hear that you found the response clear and understandable. If you have any more questions or need further assistance, feel free to ask.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants