将位数组转换为集合
convert bitarray to set
如何将bitarray转换为c++快速设置?
每个实际的位数组都有 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)。两种套餐都可以接受。
位数组在内存中是连续的。位数组的第一位与 simd 正确对齐。现在我正在使用带有 std::vector 的自定义内存分配器来保存位数组。位数组中每 1 位在内存中占 1 位。
谢谢。
更新:
this so question does the reverse
loop through bits in c
How to define and work with an array of bits in C?
gmpy 使用 gmp library. scan1 seems find first set, as in wikipedia here
的 scan1 函数
如果我理解你的问题:
for (int i = 0; i < 750000; ++i) {
if (bitarray_has(bitarray, i)) {
set_of_numbers.push_back(i);
}
}
我不认为步行 bitarray
会特别慢,但如果您知道将创建多少元素,push_back()
可以做得更快。然后你可以使用reserve()
预分配内存。
代码:
#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);
}
结果(用icc -O3 code.cpp -lrt编译)
...
timing per cycle: 0.000739613
print result
0.0008 秒转换 768000 位设置。但是每个周期至少有10,000个768,000位的数组。即每个周期 8 秒。就是慢。
如何将bitarray转换为c++快速设置? 每个实际的位数组都有 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)。两种套餐都可以接受。
位数组在内存中是连续的。位数组的第一位与 simd 正确对齐。现在我正在使用带有 std::vector 的自定义内存分配器来保存位数组。位数组中每 1 位在内存中占 1 位。
谢谢。
更新:
this so question does the reverse
loop through bits in c
How to define and work with an array of bits in C?
gmpy 使用 gmp library. scan1 seems find first set, as in wikipedia here
的 scan1 函数如果我理解你的问题:
for (int i = 0; i < 750000; ++i) {
if (bitarray_has(bitarray, i)) {
set_of_numbers.push_back(i);
}
}
我不认为步行 bitarray
会特别慢,但如果您知道将创建多少元素,push_back()
可以做得更快。然后你可以使用reserve()
预分配内存。
代码:
#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);
}
结果(用icc -O3 code.cpp -lrt编译)
...
timing per cycle: 0.000739613
print result
0.0008 秒转换 768000 位设置。但是每个周期至少有10,000个768,000位的数组。即每个周期 8 秒。就是慢。