Reputation: 724
For the data structure I'm currently making, I need to pack the integers closely together. This means, that if the maximum element in a vector is n, I would use at most lg n bits to represent it. Thus, I treat a vector of integers like a list of bits. My current solution works just fine - but I need to know if I can speed up the unpacking of an integer. That lookup operation is a quite integral part of the search query to my data structure.
// uint is an unsigned 32 bit integer (std::uint32_t)
uint
Data::findInt(const std::vector<uint>& input, int size, int pos) {
pos = pos*size;
int end = pos+size;
int firstc = pos/32;
int secondc = end/32;
int ipos = pos % 32;
int jpos = end % 32;
if(firstc == secondc) {
uint number = input.at(firstc);
number = number >> (32 - end);
number = number & ((1 << size) - 1);
return number;
}
// else
uint number = input.at(firstc);
number = number << (jpos);
number = number & ((1 << size) -1);
uint number2 = input.at(secondc);
number2 = number2 >> (32 - jpos);
number2 = number2 & ((1 << jpos) - 1);
return number + number2;
}
std::vector<uint>
Data::packBits(const std::vector<uint>& input, int size) {
std::vector<char> bits = translatetobits(input, size);
while(bits.size() % 32 != 0) {
bits.push_back(0);
}
std::vector<uint> packedbits;
for(int i = 0; i < bits.size(); i += 32) {
uint res = 0;
for(int j = 0; j < 31; ++j) {
res += (bits.at(i+j));
res = res << 1;
}
res += (bits.at(i+31));
packedbits.push_back(res);
}
// Current lookup requires an empty entry - should be fixed
packedbits.push_back(0);
return packedbits;
}
I can only fetch one integer at a time and the index of a look-up operation jumps quite arbitrarily around, so I can't batch look-ups together. Does anyone have a good idea for speeding up the look-up?
Upvotes: 0
Views: 306
Reputation: 275740
at
is checked. Check bounds once, not each interaction with the vector.
Consider using raw pointers instead of vectors for the low level operations.
Your packing is extremely inefficient -- it does memory allocation. Why in gods name.
You should be using fixed sized data, not generic uint
s.
You have duplicated code calculating number
. Consider eliminating. The constant 32
in that code is a matter of how the bits where packed -- pack in a different way, save an operation.
You can optimize for branclessness if you want, but that will probably not grant a performance increase (it will grant a worst-case performance increase, but not repeated operations, as branch predictors are pretty solid). One possibility is to always unpack your data into a 64 bit unsigned type, then shift it away: I think there are ways to do it so that the 2nd lookup just injects zeros, or data that gets masked out, if it isn't needed.
Upvotes: 1