Vector splitting and reassigning causes seg fault when using 8-byte vectors
I add everything in an array of 256 bytes by adding the second half into the first half.
The algorithm is the following pseudo-code:
sum(u8 vector) vector[0..128] += vector[128..256] vector[0..64] += vector[64..128] vector[0..32] += vector[32..64] vector[0..16] += vector[16..32] vector[0..8] += vector[8..16] vector[0..4] += vector[4..8] vector[0..2] += vector[2..4] vector += vector
Now, I implemented this using some very unsafe C++ with GNU vector extensions, and it segfaults once it uses the 8-byte vector:
vector[0..8] += vector[8..16]
Yet I can't tell why it sucessfully executes the first 4 statements.
In my implementation, I perform each line of the above via a call to
sum_half. The function reinterprets the longest vector as two smaller vectors based on the starting byte offset of the vector, and with the second vector based off of the byte offset of the first, offset further by the length of the new vector.
Can anyone review the code and determine what causes the segfault?
...vector casts to integers and vice versa?
This is never done?
I only use vector<->pointer casts.
For example, given the vector
vec<4> v = [ 1, 1, 1, 1 ], I take the address of the zeroth element (
&v), and the middle of the vector (
&v), and reinterpret both as
vec<2>*, then load them as
&vec<2> and perform the addition.
Because the idea doesn't map as well to code, I get the byte offset of the vector, for example:
v = [ 1, 2, 3, 4 ] // ^ reference to first offset = reinterpret_cast<...>(...)
add half of the vector's length:
length = 4 offset + length >> 1 // offset == &v
and load the second half as a vector, which in the example above would be
[ 3, 4 ].
I carefully made sure to not accidentally reinterpret any plain numbers as pointers (I accidentally reinterpreted a u8 as a vector pointer once).
Does the above explanation help grasp the situation?
Unrelated, but it wasn't there before, and it's terrifying
Ha, if you ever code in assembly or smth all the bugs just kinda sit there until 2 hours later when you've added 100 more lines of code and they all just emerge and you have no idea wtf is going on because everything was working before... yeah.
Also I understand your code and there doesn't seem to be anything immediately wrong with it, though admittedly I don't use C++ so I'm not aware of any of it's potential quirks.
Anyways one pattern I did notice is that this seg fault is only present with a SHIFT of 4. Doesn't seem like that special of a number tho unless C++ uint8_t's or vectors have some grudge with 4.
@realTronsi Early in the code, I had severe alignment issues, so the entire second half of the vector would be overwritten with garbage upon every call. Technicially it was okay since after every call the second half is unused, wasted memory, but it was a bug nonetheless.
After correctly aligning the vector (I was initially using an array), and fixing my types, it seemed to work fine, but now there's a bit of garbage at the end, and I'm not sure why that is.
@realTronsi I think x86 only has packed integer instructions for operating on 128 bits at a time, so I think that would be 16 sets of 8 bits at a time, which maps exactly to the shift of 4, since
0x100 >> 4 = 16. Not sure if it's relevant though.
I'm not seeing any xmm registers or operations being emit for
Updated to emit asm & machine code when pressing run, could you check it out?
@xxpertHacker I can't understand this machine code, obviously. Like how am I supposed to read this
.text._ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St17basic_string_viewIS3_S4_E,"axG",@progbits,_ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St17basic_string_viewIS3_S4_E,comdat .weak _ZStlsIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_St17basic_string_viewIS3_S4_E
anyways just take your question to SO then. If you get a response there let me know because I'm curious as well