如何使用c ++快速转换bitarray? 每个实际的比特阵列都有750,000比特。
示例1:
bitarray: 01011111
set: {0,1,2,3,4,5,7}
or set: {1,3,4,5,6,7}
示例2:
bitarray: 0101 1111 0001 0001
set: {0,4,8,9,10,11,12,14}
or set: {1,3,4,5,6,7,11,15}
该集合是一个由32位整数组成的数组(uint32_t)。这两种方法都是可以接受的。
bitarray在内存中是连续的。比特阵的第一位对于simd具有正确的对齐。现在我使用带有std :: vector的自定义内存分配器来保存bitarray。在bitarray中每1位存储器中有1位。
感谢。
更新
this so question does the reverse
How to define and work with an array of bits in C?
gmpy使用gmp library的scan1函数。 scan1似乎找到了第一个设置,就像维基百科here
一样答案 0 :(得分:1)
如果我理解你的问题:
for (int i = 0; i < 750000; ++i) {
if (bitarray_has(bitarray, i)) {
set_of_numbers.push_back(i);
}
}
我不相信步行bitarray
会特别慢,但如果您知道将创建多少元素,push_back()
可以更快。然后,您可以使用reserve()
预分配内存。
答案 1 :(得分:0)
代码:
df <-
data.frame(
Name = LETTERS[1:5]
, ID = factor(formatC(c(1,4,4,6,7), width = 3, flag = "0")
, levels = formatC(1:7, width = 3, flag = "0") )
)
table(df)
结果(使用icc -O3 code.cpp -lrt编译)
#include <iostream>
#include <vector>
#include <time.h>
using namespace std;
template <typename T>
uint32_t bitarray2set(T& v, uint32_t * ptr_set){
uint32_t i;
uint32_t base = 0;
uint32_t * ptr_set_new = ptr_set;
uint32_t size = v.capacity();
for(i = 0; i < size; i++){
find_set_bit(v[i], ptr_set_new, base);
base += 8*sizeof(uint32_t);
}
return (ptr_set_new - ptr_set);
}
inline void find_set_bit(uint32_t n, uint32_t*& ptr_set, uint32_t base){
// Find the set bits in a uint32_t
int k = base;
while(n){
if (n & 1){
*(ptr_set) = k;
ptr_set++;
}
n = n >> 1;
k++;
}
}
template <typename T>
void rand_vector(T& v){
srand(time(NULL));
int i;
int size = v.capacity();
for (i=0;i<size;i++){
v[i] = rand();
}
}
template <typename T>
void print_vector(T& v, int size_in = 0){
int i;
int size;
if (size_in == 0){
size = v.capacity();
} else {
size = size_in;
}
for (i=0;i<size;i++){
cout << v[i] << ' ';
}
cout << endl;
}
int main(void){
const int test_size = 6000;
vector<uint32_t> vec(test_size);
vector<uint32_t> set(test_size*sizeof(uint32_t)*8);
rand_vector(vec);
//for (int i; i < 64; i++) vec[i] = -1;
//cout << "input" << endl;
print_vector(vec);
//cout << "calculate result" << endl;
int i;
int rep = 10000;
uint32_t res_size;
struct timespec tp_start, tp_end;
clock_gettime(CLOCK_MONOTONIC, &tp_start);
for (i=0;i<rep;i++){
res_size = bitarray2set(vec, set.data());
}
clock_gettime(CLOCK_MONOTONIC, &tp_end);
double timing;
const double nano = 0.000000001;
timing = ((double)(tp_end.tv_sec - tp_start.tv_sec )
+ (tp_end.tv_nsec - tp_start.tv_nsec) * nano) /(rep);
cout << "timing per cycle: " << timing << endl;
cout << "print result" << endl;
//print_vector(set, res_size);
}
0.0008秒将768000位转换为设置。但是每个周期至少有10,000个768,000位的数组。这是每个周期8秒。那很慢。