簡體   English   中英

C ++快速高效的方式對40字節數組執行bit_count和AND操作

[英]C++ Fast and Efficient way to perform bit_count and AND operation on 40 byte array

在我的項目中,我需要對兩個大小為40字節(320位)的二進制數組進行“與”運算,然后在C ++中計算設置的位數。 我找到了一些算法可以做到這一點,但是我想知道用c ++實現它的最快方法是什么。 我的意思是哪種c ++數據類型合適?(未使用char *,unsigned int 32,u_int64,...)。 我知道許多算法都與32位整數兼容,盡管我的數組大小為40個字節。

那么此鏈接中描述的算法又如何呢: 快速位計數技術哪一個更快?

是const類型更好還是沒有區別?

任何幫助將非常感激。

這是一次遍歷數組的版本,一次包含4個字節,需要10次迭代:

uint32_t *arr1_int = (uint32_t*) arr1;
uint32_t *arr2_int = (uint32_t*) arr2;
int i;
int bits_set = 0;

for (i = 0; i < 10; i++) {
    uint32_t v = arr1_int[i] & arr2_int[i];

    /* http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel */
    v = v - ((v >> 1) & 0x55555555);                   
    v = (v & 0x33333333) + ((v >> 2) & 0x33333333);    
    bits_set += ((v + (v >> 4) & 0xF0F0F0F) * 0x1010101) >> 24;
}

使用現代CPU,您可以使用編譯器內在函數更快地完成此操作。 例如,在具有Visual C ++的64位CPU上:

#include <intrin.h>

__int64 *arr1_int = (__int64*) arr1;
__int64 *arr2_int = (__int64*) arr2;
int bits_set = 0;

/* 40 / 8 bytes == 5 iterations */
bits_set += __popcnt64(*arr1_int++ & *arr2_int++);
bits_set += __popcnt64(*arr1_int++ & *arr2_int++);
bits_set += __popcnt64(*arr1_int++ & *arr2_int++);
bits_set += __popcnt64(*arr1_int++ & *arr2_int++);
bits_set += __popcnt64(*arr1_int++ & *arr2_int++);

但這只是考慮到性能,如果您只是想要一些能正常工作的可讀代碼,就一定要遵循Rob的建議。

我的意思是哪種c ++數據類型合適?

std::bitset<320>

您想出的任何算法都應在速度和便利性上與該算法進行比較:

std::bitset<320> first;
std::bitset<320> other;

// twiddle bits here ...

std::bitset<320> and_result(first & other);
std::size_t number_of_bits(and_result.count());

如果替代方法的執行速度不快,則只需使用上述代碼即可。 它可以清楚地表達您的意圖,並避免以后出現維護麻煩。

這樣簡單的事情應該足夠快:

const uint8_t LUT[256] = { 0, 1, 1, 2, ..., 8 }; // pop count LUT for bytes

int count_bits(const uint8_t *a1, const uint8_t *a2, int n)
{
    int count = 0;

    for (int i = 0; i < n; ++i)
    {
        count += LUT[a1[i] & a2[i]];
    }
    return count;
}

每個字節有3個負載和2個ALU操作,即40字節用例的120個負載和80個ALU ops。

嘗試一下,對其進行概要分析,如果它不夠快,那么您可以查看可能更快的更復雜的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM