Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 寻找第一个可用位的最佳方法_C - Fatal编程技术网

C 寻找第一个可用位的最佳方法

C 寻找第一个可用位的最佳方法,c,C,给定一个非单整数数组(每个有4个八位组),找到第一个至少有一个“0”位的元素及其LSB索引的最佳方法是什么 e、 g:式中n=9 unsinged int uIntArray[] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff9f, 0x00000000, 0x00000000, 0x00000000, 0x00000000, }; 答复: 我只能想

给定一个非单整数数组(每个有4个八位组),找到第一个至少有一个“0”位的元素及其LSB索引的最佳方法是什么

e、 g:式中n=9

unsinged int uIntArray[] = {
    0xffffffff,
    0xffffffff,
    0xffffffff,
    0xffffffff,
    0xffffff9f,
    0x00000000,
    0x00000000,
    0x00000000,
    0x00000000,
};
答复:

我只能想到:

int main (void)
{
    bool found_f = false;
    int n = 9;  //our test case value
    unsigned int uIntArray[] = {
        0xffffffff,
        0xffffffff,
        0xffffffff,
        0xffffffff,
        0xffffff8f,
        0x00000000,
        0x00000000,
        0x00000000,
        0x00000000,
    };  

    unsigned int uIntBits [32] = {
        1, 2, 4, 8, 16, 32, 64, 128,
            256, 512, 1024, 2048, 4096, 8192, 16384, 32768,
            65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608,
            16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648
    };      

    unsigned int idx, jdx;
    int ele_idx = -1; 
    int bit_idx = -1;

    for (idx =0; idx < n; idx ++) {
        if (uIntArray[idx] < UINT_MAX) { /* our candidate */
            for (jdx =0; jdx < 32; jdx ++)  {
                if ((uIntBits[jdx] & uIntArray[idx])) {
                    ele_idx = idx; 
                    bit_idx = jdx;
                    found_f = true;
                    break;
                }   
            }   
        }   
        if(found_f) {
            break;
        }   
    }   
    fprintf (stderr, "\nEleIdx[%d] BitIdx[%d]\n", ele_idx, bit_idx);
    return 0;
}   
int main(无效)
{
bool found_f=false;
int n=9;//我们的测试用例值
无符号整数uIntArray[]={
0xffffffff,
0xffffffff,
0xffffffff,
0xffffffff,
0xFFFF8F,
0x00000000,
0x00000000,
0x00000000,
0x00000000,
};  
无符号整数uIntBits[32]={
1, 2, 4, 8, 16, 32, 64, 128,
256, 512, 1024, 2048, 4096, 8192, 16384, 32768,
65536, 131072, 262144, 524288, 1048576, 2097152, 4194304, 8388608,
16777216, 33554432, 67108864, 134217728, 268435456, 536870912, 1073741824, 2147483648
};      
无符号整数idx,jdx;
int ele_idx=-1;
int位_idx=-1;
对于(idx=0;idx

有更好的方法吗?

您可以通过使用更大的数据类型来加快速度。因此,不必测试每个
int
是否为
0xffffffff
,您可以使用64位整数并根据
0xffffffffffff
进行测试

如果您愿意矢量化,您可以一次执行128位(SSE)或256位(AVX)

在所有情况下,注意数据对齐。如果不对齐,它要么无法工作,要么会使速度变慢

最后一步,您可以实际展开循环并一次测试多个单词/向量。这会给你更好的IPC。只有当你找到零时,你才会经历一个混乱的过程,缩小它是哪一位

编辑:

为了说明最后一点,您可以这样做:(我省略了案例
idx%4!=0时的清理代码)

for(idx=0;idx
但您可以在更大的数据类型上执行此操作。(如SSE/AVX向量)


这将使查找前0的区域更快,但缩小精确位的范围将更昂贵。因此,如果您的数据量较大,这种方法会更好。

您可以通过使用较大的数据类型来加快速度。因此,不必测试每个
int
是否为
0xffffffff
,您可以使用64位整数并根据
0xffffffffffff
进行测试

如果您愿意矢量化,您可以一次执行128位(SSE)或256位(AVX)

在所有情况下,注意数据对齐。如果不对齐,它要么无法工作,要么会使速度变慢

最后一步,您可以实际展开循环并一次测试多个单词/向量。这会给你更好的IPC。只有当你找到零时,你才会经历一个混乱的过程,缩小它是哪一位

编辑:

为了说明最后一点,您可以这样做:(我省略了案例
idx%4!=0时的清理代码)

for(idx=0;idx
但您可以在更大的数据类型上执行此操作。(如SSE/AVX向量)


这将使查找前0的区域更快,但缩小精确位的范围将更昂贵。因此,如果您的数据量很大,这种方法会更好。

要找到第一个元素,您可以观察到,如果数字没有
0
位,那么它必须是
0xff..ff
,因此不必显式检查每个位,只需将其与
0xff..ff
进行比较即可


要找到该数字的最低有效位,我相信您仍然需要检查每个位。

要找到第一个元素,您可以观察到,如果该数字没有
0
位,那么它必须是
0xff..ff
,因此不必显式检查每个位,您只需将其与
0xff..ff
进行比较即可


要找到该数字的最低有效位,我相信您仍然需要检查每个位。

x
中最低有效
0
的索引是
~x
中最低有效
1
的索引。为了找到后者,只需计算
~x
中的尾随零。有很多方法可以做到这一点,请看这里

使用最后一种方法(基于Debrijn序列),搜索将如下所示

static const unsigned MultiplyDeBruijnBitPosition[32] = 
{
  0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 
  31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};

for (idx = 0; idx < n; idx ++)
  if (uIntArray[idx] < UINT_MAX)
    break;

if (idx < n) {
  unsigned v = ~uIntArray[idx];
  int bit_idx = MultiplyDeBruijnBitPosition[((v & -v) * 0x077CB531u) >> 27];
  fprintf(stderr, "\nEleIdx[%d] BitIdx[%d]\n", idx, bit_idx);
}
static const unsigned multipledbruijnbitposition[32]=
{
0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 
31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};
对于(idx=0;idx>27];
fprintf(stderr,“\nEleIdx[%d]BitIdx[%d]\n”,idx,bit_idx);
}

x
中最低有效
0
的索引是
~x
中最低有效
1
的索引。为了找到后者,只需计算
~x
中的尾随零。有很多方法可以做到这一点,请看这里

使用最后一种方法(基于Debrijn序列),搜索
for (idx =0; idx < n; idx += 4) {
    unsigned int test = uIntArray[idx];
    test &= uIntArray[idx + 1];
    test &= uIntArray[idx + 2];
    test &= uIntArray[idx + 3];

    if (test < UINT_MAX){
        //  Find which bit it is.

    }
}
static const unsigned MultiplyDeBruijnBitPosition[32] = 
{
  0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 
  31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
};

for (idx = 0; idx < n; idx ++)
  if (uIntArray[idx] < UINT_MAX)
    break;

if (idx < n) {
  unsigned v = ~uIntArray[idx];
  int bit_idx = MultiplyDeBruijnBitPosition[((v & -v) * 0x077CB531u) >> 27];
  fprintf(stderr, "\nEleIdx[%d] BitIdx[%d]\n", idx, bit_idx);
}
/* Return the position of the first clear bit in the array,
 * or -1 if none found.
 *  arr:  array of uint32_t to search
 *  sz:   number of elements in arr
 */
int findClearBit(uint32_t *arr, int sz)
{
  int i;
  for (i = 0; i < sz; i++) {
    if (~arr[i]) {
      switch (~arr[i] & (arr[i] + 1)) {
        case 1 << 31:  return (i * 32) + 31;
        case 1 << 30:  return (i * 32) + 30;
        case 1 << 29:  return (i * 32) + 29;
        case 1 << 28:  return (i * 32) + 28;
        case 1 << 27:  return (i * 32) + 27;
        case 1 << 26:  return (i * 32) + 26;
        case 1 << 25:  return (i * 32) + 25;
        case 1 << 24:  return (i * 32) + 24;
        case 1 << 23:  return (i * 32) + 23;
        case 1 << 22:  return (i * 32) + 22;
        case 1 << 21:  return (i * 32) + 21;
        case 1 << 20:  return (i * 32) + 20;
        case 1 << 19:  return (i * 32) + 19;
        case 1 << 18:  return (i * 32) + 18;
        case 1 << 17:  return (i * 32) + 17;
        case 1 << 16:  return (i * 32) + 16;
        case 1 << 15:  return (i * 32) + 15;
        case 1 << 14:  return (i * 32) + 14;
        case 1 << 13:  return (i * 32) + 13;
        case 1 << 12:  return (i * 32) + 12;
        case 1 << 11:  return (i * 32) + 11;
        case 1 << 10:  return (i * 32) + 10;
        case 1 << 9:   return (i * 32) + 9;
        case 1 << 8:   return (i * 32) + 8;
        case 1 << 7:   return (i * 32) + 7;
        case 1 << 6:   return (i * 32) + 6;
        case 1 << 5:   return (i * 32) + 5;
        case 1 << 4:   return (i * 32) + 4;
        case 1 << 3:   return (i * 32) + 3;
        case 1 << 2:   return (i * 32) + 2;
        case 1 << 1:   return (i * 32) + 1;
        case 1:        return (i * 32);
        default:       return -1;
      }
    }
  }
  return -1;
}