badger icon indicating copy to clipboard operation
badger copied to clipboard

make putNode correct

Open zhiqiangxu opened this issue 5 years ago • 10 comments

s.buf bytes may be not aligned, so the correct implementation should take that into consideration.

Update

Switched to use makeAlignedBuf instead.


This change is Reviewable

zhiqiangxu avatar Mar 24 '20 01:03 zhiqiangxu

Hey @zhiqiangxu, can you add some more information to the PR description? I'm trying to understand why do we need this change and what are the implications of it.

jarifibrahim avatar Mar 24 '20 08:03 jarifibrahim

node address = address of first element + offset

In order to make sure node address is aligned, should consider address of first element, which is not necessarily aligned.

It's wrong to only consider offset

zhiqiangxu avatar Mar 24 '20 08:03 zhiqiangxu

The spec only guarantees :

the first (64-bit) word in a variable or in an allocated struct, array, or slice can be relied upon to be 64-bit aligned.

So it's not guaranteed that the first element of a []byte is 8 byte aligned, though the first element of []uint64 is always 8 byte aligned.

zhiqiangxu avatar Mar 25 '20 04:03 zhiqiangxu

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar Apr 24 '20 16:04 stale[bot]

@zhiqiangxu The review for this PR is pending because I don't understand alignment issues properly. I'll read some stuff about it and then review this PR. Apologies for the delay.

jarifibrahim avatar Apr 24 '20 17:04 jarifibrahim

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

stale[bot] avatar May 24 '20 17:05 stale[bot]

@zhiqiangxu I did a small benchmark to compare the performance. This is the BenchmarkWrite function in the skl package.

name            old time/op    new time/op    delta
Write-8          522ns ± 8%     563ns ± 3%  +7.87%  (p=0.001 n=10+8)

The new changes seem to be slower. Do you know why it could be slower?

jarifibrahim avatar May 26 '20 11:05 jarifibrahim

Maybe because of the extra bounding check and more bytes involved, but pity that I don't know how to optimize it:(

zhiqiangxu avatar Jun 01 '20 16:06 zhiqiangxu

The rationale looks correct to me: Golang doesn't guarantee that the underlying memory block of a []byte is aligned. It only guarantees that the underlying memory block of an array follows the alignment guarantees of each its elements:

From https://golang.org/ref/spec#Size_and_alignment_guarantees:

For a variable x of array type: unsafe.Alignof(x) is the same as the alignment of a variable of the array's element type.

So a []uint64 will be aligned to 64 bit on platforms that requires that. But a []byte will not.

Based on this, I can suggest the following:

func makeAligned(n int64) []byte {
	buf := make([]uint64, n>>3)
	head := (*reflect.SliceHeader)(unsafe.Pointer(&buf))
	head.Len = int(n)
	head.Cap = int(n)
	return *(*[]byte)(unsafe.Pointer(head))
}

It doesn't seem to have any measurable performance impact.

damz avatar Jul 02 '20 16:07 damz

CLA assistant check
Thank you for your submission! We really appreciate it. Like many open source projects, we ask that you sign our Contributor License Agreement before we can accept your contribution.
You have signed the CLA already but the status is still pending? Let us recheck it.

CLAassistant avatar Apr 29 '22 07:04 CLAassistant