【问题标题】:Bit selection algorithm位选择算法
【发布时间】:2018-05-20 11:18:34
【问题描述】:

我想找到一种有效的方法来使用 C 中另一个流的位从一个流中选择位。处理的数据量是 TB,因此速度很重要。

“位选择器”所做的只是从位序列中选择某些位。例如,如果源流是 [ 1, 0, 1, 0, 1, 0, 1 ] 并且选择标准是 [ 1, 1, 0, 0, 1, 0, 0 ] 那么结果将是 [ 1 , 0, 1 ]。

执行此操作的示例如下:

uint64_t source[5];
source[0] = 1234567890987654321;
source[1] = 3456789098765432198;
source[2] = 5678909876543219876;
source[3] = 7890987654321987654;
source[4] = 9098765432198765432;
uint64_t selector[5];
selector[0] = 8214263800482614621;
selector[1] = 4251759498365531188;
selector[2] = 1628009771533217836;
selector[3] = 6890182644227957152;
selector[4] = 3018964452491735032;
size_t count_values = 5;
uint64_t result[5];

size_t xCurrentResultBits = 0;
uint64_t result_value = 0;
size_t result_index = 0;
for( size_t xSelector = 0; xSelector < count_values; xSelector ){
   uint64_t current_selector = selector[ xSelector ];
   uint64_t current_source = source[ xSelector ];
   for( size_t bit = 0; bit < 64; bit++ ){
      uint64_t mask = 1;
      mask = mask << bit;
      uint64_t selector_value = current_selector | mask;
      if( selector_value > 0 ){ // keep the bit in the source
         uint64_t source_value = current_source | mask;
         result_value = result_value << 1;
         if( source_value > 0 ) result_value = result_value + 1;
         xCurrentResultBits++
      } else {
         // throw away source bit
      }
      if( xCurrentResultBits == 63 ){ // filled up a result value
         result[ result_index ] = result_value;
         result_index++;
         result_value = 0;
         xCurrentResultBits = 0;
      }
   }
}

问题是这种方法可能比它可能的要慢很多。有没有一种众所周知的算法可以快速做到这一点?

【问题讨论】:

  • 这个算法有什么作用?例如selector_value = current_selector | mask; 总是非零,所以下一个if 看起来很奇怪
  • 这些数据来自哪里?可能来自某些 IO 通道。这比你的算法慢得多。所以在分析并证明它是一个瓶颈之前,我不会担心它。
  • mask &lt;&lt; bit; 表达式无效。
  • 与其向我们倾倒一堆密集的代码并期望我们了解您要解决的问题,不如用文字向我们解释。你在这里所做的类似于向我展示一个可以完成我不熟悉的工作的工具,并要求我帮助你设计一个类似的工具来完成你甚至没有定义的事情。
  • 你的意思是this

标签: c algorithm bit-manipulation


【解决方案1】:

我会根据查找表逐字节进行。

创建一个查找表,为您提供要与输出的当前字节和下一个字节进行或运算(移位后)的位模式。该表由 [sourceByte][selectorByte] 索引,因此它是一个 256*256 的字节值表。

将表格结果移动当前输出字节中已经占用的位数,然后将其移到当前和下一个字节(或者可能使用更大的块作为结果)。

将输出位位置和字节指针前进选择器字节的位数(另一个表字节[256]可能比位摆弄更容易)。

但最后,您必须分析程序并尝试哪种方法更快(如果位摆弄确实占运行时的显着部分)。

【讨论】:

    猜你喜欢
    • 2013-10-25
    • 2021-07-30
    • 2015-07-15
    • 2020-05-04
    • 1970-01-01
    • 1970-01-01
    • 2016-06-09
    • 1970-01-01
    • 2022-07-06
    相关资源
    最近更新 更多