Nasıl 32-bit bir tamsayı kümesi bit sayısını saymak için?
8 bit 7 numaralı temsil eden bu gibi görünüyor:
00000111
Üç biti ayarlanır.
32-bit bir tamsayı kümesi bit sayısını belirlemek için algoritmalar nelerdir?
CEVAP
Bu olarak bilinir 'Hamming Weight', '' veya 'yan ayrıca'. popcount
'En iyi' algoritma gerçekten ne olduğu ve kullanım desen ne olduğuna bağlı.
Bazı İşlemciler tek bir yerleşik öğretim yapmak zorunda ve diğerleri bit vektörler üzerinde hareket eden paralel talimatları var. Paralel talimatları (desteklenen nerede İşlemciler üzerinde x 86 popcnt
, gibi) neredeyse kesinlikle hızlı olacak. Başka mimarileri yavaş bir talimat döngüsü başına bir bit test eden microcoded bir döngü ile hayata sahip olabilirbelirtilmeli).
Önceden girilmiş bir tablo arama yöntemi ise CPU büyük önbellek ve/varsa çok hızlı olabilir ya da sıkı bir döngü içinde bu talimatları çok yapıyorsun. 'Önbellek', CPU, ana bellekten. tablonun bazı getirmek için sahip olduğu bayan bir masraf yüzünden acı olabilir ancak
Eğer bayt 0 en çok 1 En çok olacağını biliyorsanız, o zaman bu senaryolar için çok verimli bir algoritma vardır.
Çok iyi bir genel amaçlı bir algoritma aşağıdaki, olarak bilinir inanıyorum '' veya 'değişken duyarlıklı SWAR algoritması'. paralel C-gibi sözde bir dil bu, belirli bir dil için çalışmaya ayarlamak gerekebilir (örneğin C ve >uint32_t kullanarak ifade ettim ^< . Java):
int NumberOfSetBits(int i)
{
// Java: use >>> instead of >>
// C or C : use uint32_t
i = i - ((i >> 1) & 0x55555555);
i = (i & 0x33333333) ((i >> 2) & 0x33333333);
return (((i (i >> 4)) & 0x0F0F0F0F) * 0x01010101) >> 24;
}
Bu en kötü durum incelenen herhangi bir davranışı vardır, bu yüzden verimli bir şekilde kullanımı desen ya da bunu atmak değerleri ile ilgileneceğiz.
Bit-SWAR bu algoritma tek tamsayı bir kayıt yerine çoklu vektör öğeleri aynı anda yapılması, SIMD ancak kullanılabilir popcount Talimat ile CPU üzerinde bir hızlanma için parallelize. (86-64 örneğin herhangi bir İŞLEMCİ üzerinde çalışacak olan kod değil, sadece Çekirdek veya üstü.)
Ancak, popcount için vektör talimatları kullanmak için en iyi yolu, genellikle değişken bir shuffle kullanarak paralel olarak, her bayt bir seferde 4 bit için tablo-bir arama yapmak için. (4 bit 16 giriş bir tablo vektör bir kayıt yapıldı) dizin.
Intel İşlemciler üzerinde, 64 bit donanım popcnt talimat 2, ama if your compiler gets it just right yaklaşık bir faktör tarafından SSSE3 PSHUFB
bit-parallel implementation daha iyi performans olabilir. Aksi takdirde SSE önemli ölçüde karlı çıkın. Yeni derleyici sürümleripopcnt false dependency problem on IntelBu farkında.
Referanslar:
http://graphics.stanford.edu/~seander/bithacks.html
http://en.wikipedia.org/wiki/Hamming_weight
http://gurmeetsingh.wordpress.com/2008/08/05/fast-bit-counting-routines/
http://aggregate.ee.engr.uky.edu/MAGIC/#Population Count (Ones Count)
Nasıl bir sayfada saatlerin toplam say...
Nasıl bir Liste içinde bir öğenin yine...
Nasıl verimli bir şekilde anahtarları/...
Nasıl bir dizin özyinelemeli olarak tü...
Bu nasıl bir dizi kontrol etmek için y...