Jump to content

Найти первый набор

(Перенаправлено с подсчета ведущих нулей )

В компьютерном программном и аппаратном обеспечении поиск первого набора ( ffs ) или поиск первого набора — это битовая операция , которая, учитывая беззнаковое машинное слово , [номер 1] обозначает индекс или позицию младшего бита, установленного на единицу в слове, отсчитывающемся от позиции младшего бита. Почти эквивалентная операция — подсчет конечных нулей ( ctz ) или количества конечных нулей ( ntz ), которая подсчитывает количество нулевых битов, следующих за младшим значащим битом. Дополнительная операция, которая находит индекс или позицию старшего бита набора, — это log base 2 , названная так потому, что она вычисляет двоичный логарифм ⌊log 2 (x)⌋ . [1] Это тесно связано с подсчетом ведущих нулей ( clz ) или количеством ведущих нулей ( nlz ), который подсчитывает количество нулевых битов, предшествующих самому старшему биту. [номер 2] Существует два распространенных варианта поиска первого набора: определение POSIX , которое начинает индексацию битов с 1, [2] здесь обозначен ffs, а вариант, который начинает индексацию битов с нуля, что эквивалентно ctz и поэтому будет называться этим именем.

Большинство современных архитектур набора команд ЦП предоставляют один или несколько из них в качестве аппаратных операторов; программная эмуляция обычно предоставляется для всех недоступных функций либо в виде встроенных функций компилятора , либо в системных библиотеках .

Учитывая следующее 32-битное слово:

0000 0000 0000 0000 1000 0000 0000 1000

Операция подсчета конечных нулей вернет 3, а операция подсчета ведущих нулей возвращает 16. Операция подсчета ведущих нулей зависит от размера слова: если это 32-битное слово было усечено до 16-битного слова, подсчет ведущих нулей вернет ноль. . Операция поиска первого набора вернет 4, что указывает на четвертую позицию справа. База усеченного журнала 2 равна 15.

Аналогично, учитывая следующее 32-битное слово, побитовое отрицание вышеуказанного слова:

1111 1111 1111 1111 0111 1111 1111 0111

Операция подсчета конечных единиц вернет 3, операция подсчета ведущих единиц вернет 16, а операция поиска первого нуля ffz вернет 4.

Если слово равно нулю (биты не установлены), подсчет начальных нулей и подсчет конечных нулей возвращают количество битов в слове, а ffs возвращает ноль. Как логарифмическая реализация с основанием 2, так и реализация поиска первого набора с отсчетом от нуля обычно возвращают неопределенный результат для нулевого слова.

Аппаратная поддержка

[ редактировать ]

Многие архитектуры включают инструкции для быстрого выполнения поиска первого набора и/или связанных с ним операций, перечисленных ниже. Наиболее распространенной операцией является подсчет начальных нулей (clz), вероятно, потому, что все остальные операции могут быть эффективно реализованы с ее помощью (см. Свойства и отношения ).

Платформа Мнемоника Имя Ширина операнда Описание По заявке на 0
ARM ( архитектура ARMv5T и более поздние версии )
кроме Cortex-M0/M0+/M1/M23
клз [3] Подсчитайте ведущие нули 32 клз 32
ARM ( архитектура ARMv8-A ) клз Подсчитайте ведущие нули 32, 64 клз Ширина операнда
АВР32 клз [4] Подсчитайте ведущие нули 32 клз 32
ДЕК Альфа ctlz [5] Подсчитайте ведущие нули 64 клз 64
cttz [5] Подсчитайте конечные нули 64 КТЗ 64
Intel 80386 и более поздние версии BSF [6] Битовое сканирование вперед 16, 32, 64 КТЗ Неопределенный; устанавливает нулевой флаг
бср [6] Битовое сканирование, обратное 16, 32, 64 База журналов 2 Неопределенный; устанавливает нулевой флаг
x86 с поддержкой BMI1 или ABM lzcnt [7] Подсчитайте ведущие нули 16, 32, 64 клз Ширина операнда; наборы с флагом
x86 с поддержкой ИМТ1 tcnt [8] Подсчитайте конечные нули 16, 32, 64 КТЗ Ширина операнда; наборы с флагом
Итаний клз [9] Подсчитайте ведущие нули 64 клз 64
МИПС32/МИПС64 клз [10] [11] Посчитать ведущие нули в Word 32, 64 клз Ширина операнда
Кло [10] [11] Посчитайте ведущие в Word 32, 64 Кло Ширина операнда
Моторола 68020 и новее лучший друг [12] Найдите первый в битовом поле Произвольный База журналов 2 Смещение поля + ширина поля
ПДП-10 см. Прыгай, если найдешь первого 36 клз 0; нет операции
ПИТАНИЕ / PowerPC / Питание ISA cntlz/cntlzw/cntlzd [13] Подсчитайте ведущие нули 32, 64 клз Ширина операнда
Питание ISA 3.0 и более поздних версий cnttzw/cnttzd [14] Подсчитайте конечные нули 32, 64 КТЗ Ширина операнда
RISC-V (расширение «B») клз [15] Подсчитайте ведущие нули 32, 64 клз Ширина операнда
КТЗ [15] Подсчитайте конечные нули 32, 64 КТЗ Ширина операнда
SPARC Oracle Architecture 2011 и более поздние версии лзкнт (синоним: лзд) [16] Ведущий нулевой счет 64 клз 64
ВАКС ффс [17] Найти первый набор 0–32 КТЗ Ширина операнда; устанавливает нулевой флаг
IBM z/Архитектура флогр [18] Найдите самый левый 64 клз 64
вклз [18] Ведущие нули векторного подсчета 8, 16, 32, 64 клз Ширина операнда
вкц [18] Векторный счетчик с конечными нулями 8, 16, 32, 64 КТЗ Ширина операнда

На некоторых платформах Alpha CTLZ и CTTZ эмулируются программно.

Поддержка инструментов и библиотек

[ редактировать ]

Ряд поставщиков компиляторов и библиотек предоставляют встроенные функции компилятора или библиотечные функции для выполнения поиска первого набора и/или связанных с ним операций, которые часто реализуются с помощью приведенных выше аппаратных инструкций:

Инструмент/библиотека Имя Тип Тип(ы) входа Примечания По заявке на 0
POSIX .1-совместимая библиотека libc
4.3BSD libc
ОС Х 10.3 libc [2] [19]
ffs Библиотечная функция интервал Включает glibc . POSIX не предоставляет дополнительную базу журналов 2 / clz. 0
FreeBSD 5.3 libc.
ОС Х 10.4 libc [19]
ffsl
fls
flsl
Библиотечная функция интервал,
длинный
fls("найти последний набор") вычисляет (логарифм по базе 2) + 1. 0
FreeBSD 7.1 libc. [20] ffsll
flsll
Библиотечная функция долго долго 0
GCC 3.4.0 [21] [22]
Кланг 5.x [23] [24]
__builtin_ffs[l,ll,imax]
__builtin_clz[l,ll,imax]
__builtin_ctz[l,ll,imax]
Встроенные функции беззнаковое целое число,
беззнаковый длинный,
беззнаковый длинный длинный,
uintmax_t
Документация GCC считает результат неопределенным clz и ctz равным 0. 0 (ффс)
Визуальная Студия 2005 _BitScanForward[25]
_BitScanReverse[26]
Внутренние функции компилятора беззнаковый длинный,
беззнаковый __int64
Отдельное возвращаемое значение для указания нулевого ввода. Неопределенный
Визуальная Студия 2008 __lzcnt[27] Встроенный компилятор беззнаковое короткое,
беззнаковое целое число,
беззнаковый __int64
Полагается на аппаратную поддержку инструкции lzcnt, представленной в BMI1 или ABM . Ширина операнда
Визуальная Студия 2012 _arm_clz[28] Встроенный компилятор беззнаковое целое число Опирается на аппаратную поддержку инструкции clz, представленной в архитектуре ARMv5T и более поздних версиях . ?
Intel C++-компилятор _bit_scan_forward
_bit_scan_reverse[29] [30]
Внутренние функции компилятора интервал Неопределенный
Нвидиа КУДА [31] __clz Функции 32-bit, 64-bit Компилируется с меньшим количеством инструкций серии GeForce 400. 32
__ffs 0
ЛЛВМ llvm.ctlz.*
llvm.cttz.*[32]
Внутренний 8, 16, 32, 64, 256 язык ассемблера LLVM Ширина операнда, если второй аргумент равен 0; не определено в противном случае
GHC 7.10 (база 4.8), в Data.Bits[ нужна ссылка ] countLeadingZeros
countTrailingZeros
Библиотечная функция FiniteBits b => b Язык программирования Хаскелл Ширина операнда
C++20 , в заголовке Стандартная библиотека <bit>[33] [34] bit_ceil bit_floor
bit_width
countl_zero countl_one
countr_zero countr_one
Библиотечная функция беззнаковый символ,
беззнаковое короткое,
беззнаковое целое число,
беззнаковый длинный,
беззнаковый длинный длинный

Свойства и отношения

[ редактировать ]

Если биты помечены начиная с 1 (это соглашение, используемое в этой статье), то операции подсчета конечных нулей и поиска первого набора связаны соотношением ctz( x ) = ffs( x ) − 1 (за исключением случаев, когда входное значение равно нулю). Если биты помечены начиная с 0 , то подсчет конечных нулей и поиск первого набора являются точно эквивалентными операциями. Учитывая w бит на слово, log 2 легко вычисляется из clz и наоборот по формуле log 2 ( x ) = w - 1 - clz( x ) .

Как показано в приведенном выше примере, операции поиска первого нуля, подсчета ведущих и подсчета конечных нулей могут быть реализованы путем отрицания входных данных и использования поиска первого набора, подсчета ведущих нулей и подсчета конечных нулей. Обратное также верно.

На платформах с эффективной операцией log 2, таких как M68000, ctz можно вычислить следующим образом:

ctz( x ) = журнал 2 ( x & -x )

где & обозначает побитовое И, а -x обозначает двух дополнение до x . Выражение x & -x младшего очищает все, кроме одного бита, так что самый старший и самый последний бит совпадают.

На платформах с эффективным подсчетом ведущих нулей, таких как ARM и PowerPC, ffs можно вычислить следующим образом:

ffs( Икс ) знак равно ш - clz( Икс & ) .

И наоборот, на машинах без log 2 или clz операторов , clz можно вычислить с помощью ctz , хотя и неэффективно:

clz = w − ctz(2 ⌈лог 2 ( х )⌉ ) (что зависит от того, ctz возвращает ли w для нулевого входа)

На платформах с эффективной операцией взвешивания Хэмминга (подсчета населения), таких как SPARC . POPC[35] [36] или Блэкфин ONES, [37] есть:

ctz( x ) = popcount(( x & -x ) - 1) , [38] [39] или ctz( x ) = popcount(~( x | −x )) ,
ffs( x ) = popcount( x ^ ~− x ) [35]
clz = 32 - popcount(2 ⌈лог 2 ( х )⌉ − 1)

где ^ обозначает побитовое исключающее ИЛИ, | обозначает побитовое ИЛИ, а ~ обозначает побитовое отрицание.

Обратная задача (при заданном i получить x такой, что ctz( x ) = i ) может быть вычислена со сдвигом влево ( 1 << i ).

Операции поиска первого набора и связанные с ними операции могут быть расширены до произвольно больших битовых массивов простым способом, начиная с одного конца и продолжая до тех пор, пока слово не будет не нулевым (для ffs , ctz , clz ) или не все единицей (для ffz , clo , cto ) встречается. Древовидная структура данных, которая рекурсивно использует растровые изображения для отслеживания того, какие слова ненулевые, может ускорить этот процесс.

Программная эмуляция

[ редактировать ]

Большинство процессоров, выпущенных с конца 1980-х годов, имеют битовые операторы для ffs или эквивалентные, но некоторые современные процессоры, такие как некоторые из серии ARM-Mx, не имеют. Вместо аппаратных операторов для ffs, clz и ctz программное обеспечение может эмулировать их с помощью сдвигов, целочисленной арифметики и побитовых операторов. Существует несколько подходов в зависимости от архитектуры ЦП и, в меньшей степени, семантики языка программирования и качества генерации кода компилятора. Подходы можно условно описать как линейный поиск , двоичный поиск , поиск + поиск по таблице, умножение де Брёйна, преобразование с плавающей запятой/извлечение показателя степени и методы битового оператора (без ветвей). Существует компромисс между временем выполнения и объемом памяти, а также портативностью и эффективностью.

Программные эмуляции обычно являются детерминированными. Они возвращают определенный результат для всех входных значений; в частности, результат ввода всех нулевых битов обычно равен 0 для ffs, а длина операнда в битах для других операций.

Если у вас есть аппаратный clz или его эквивалент, ctz можно эффективно вычислить с помощью битовых операций, но обратное неверно: вычисление clz неэффективно в отсутствие аппаратного оператора.

Функция 2 ⌈лог 2 (х)⌉ (округляем до ближайшей степени двойки) с использованием сдвигов и побитовых операций ИЛИ [40] неэффективно вычислять, как в этом 32-битном примере, и еще более неэффективно, если у нас есть 64-битный или 128-битный операнд:

function pow2(x):
    if x = 0 return invalid  // invalid is implementation defined (not in [0,63])
    x ← x - 1
    for each y in {1, 2, 4, 8, 16}: x ← x | (x >> y)
    return x + 1

Поскольку ffs = ctz + 1 (POSIX) или ffs = ctz (другие реализации), можно использовать применимые алгоритмы для ctz с возможным последним шагом добавления 1 к результату и возвратом 0 вместо длины операнда для ввода все нулевые биты.

Канонический алгоритм представляет собой цикл, подсчитывающий нули, начиная с младшего разряда до тех пор, пока не встретится 1 бит:

function ctz1 (x)
    if x = 0 return w
    t ← 1
    r ← 0
    while (x & t) = 0
        t ← t << 1
        r ← r + 1
    return r

Этот алгоритм выполняет время и операции O ( n ) и на практике непрактичен из-за большого количества условных ветвей.

Таблица поиска может исключить большинство ветвей:

table[0..2n-1] = ctz(i) for i in 0..2n-1
function ctz2 (x)
    if x = 0 return w
    r ← 0
    loop
        if (x & (2n-1)) ≠ 0
            return r + table[x & (2n-1)]
        x ← x >> n
        r ← r + n

Параметр n фиксирован (обычно 8) и представляет собой компромисс между временем и пространством . Петля также может быть полностью развернута . Но при линейном поиске этот подход по-прежнему равен O(n) по числу битов в операнде.

Реализация двоичного поиска требует логарифмического количества операций и ветвей, как в этой 32-битной версии: [41] [42] Этому алгоритму также может помочь таблица, заменяющая три нижних оператора «if» таблицей поиска из 256 записей, используя первый ненулевой байт, встреченный в качестве индекса.

function ctz3 (x)
    if x = 0 return 32
    n ← 0
    if (x & 0x0000FFFF) = 0: n ← n + 16, x ← x >> 16
    if (x & 0x000000FF) = 0: n ← n +  8, x ← x >>  8
    if (x & 0x0000000F) = 0: n ← n +  4, x ← x >>  4
    if (x & 0x00000003) = 0: n ← n +  2, x ← x >>  2
    if (x & 0x00000001) = 0: n ← n +  1
    return n

Если в аппаратном обеспечении имеется оператор clz, наиболее эффективный подход к вычислению ctz выглядит следующим образом:

function ctz4 (x)
    x &= -x
    return w - (clz(x) + 1)

Алгоритм для 32-битного ctz использует последовательности де Брейна для построения минимальной идеальной хэш-функции , исключающей все ветвления. [43] [44] Этот алгоритм предполагает, что результат умножения усекается до 32 бит.

for i from 0 to 31: table[ ( 0x077CB531 * ( 1 << i ) ) >> 27 ] ← i  // table [0..31] initialized
function ctz5 (x)
    return table[((x & -x) * 0x077CB531) >> 27]

Выражение (x & -x) снова изолирует один наименее значимый бит. Тогда есть только 32 возможных слова, которые можно умножить без знака и сдвинуть хэш на правильную позицию в таблице. (Этот алгоритм не обрабатывает нулевой ввод.)

Канонический алгоритм проверяет по одному биту, начиная со старшего бита, пока не будет найден ненулевой бит, как показано в этом примере. Он выполняется за время O(n), где n — длина операнда в битах, и не является практическим алгоритмом общего использования.

function clz1 (x)
    if x = 0 return w
    t ← 1 << (w - 1)
    r ← 0
    while (x & t) = 0
        t ← t >> 1
        r ← r + 1
    return r

Усовершенствование предыдущего подхода к циклированию предполагает проверку восьми битов за раз, а затем использование 256 (2 8 ) таблица поиска записей для первого ненулевого байта. Однако этот подход по-прежнему требует O(n) во время выполнения.

function clz2 (x)
    if x = 0 return w
    t ← 0xff << (w - 8)
    r ← 0
    while (x & t) = 0
        t ← t >> 8
        r ← r + 8
    return r + table[x >> (w - 8 - r)]

Двоичный поиск может сократить время выполнения до O(log 2 n):

function clz3 (x)
    if x = 0 return 32
    n ← 0
    if (x & 0xFFFF0000) = 0: n ← n + 16, x ← x << 16
    if (x & 0xFF000000) = 0: n ← n +  8, x ← x <<  8
    if (x & 0xF0000000) = 0: n ← n +  4, x ← x <<  4
    if (x & 0xC0000000) = 0: n ← n +  2, x ← x <<  2
    if (x & 0x80000000) = 0: n ← n +  1
    return n

Самый быстрый портативный подход к моделированию clz — это комбинация двоичного поиска и поиска по таблице: поиск по 8-битной таблице (2 8 =256 1-байтовых записей) могут заменить три нижние ветви при двоичном поиске. 64-битные операнды требуют дополнительной ветки. Можно использовать поиск большей ширины, но максимальный практический размер таблицы ограничен размером кэша данных L1 на современных процессорах, который для многих составляет 32 КБ. Сохранение ветки более чем компенсируется задержкой из-за промаха в кэше L1 .

Алгоритм, аналогичный умножению де Брейна для CTZ, работает и для CLZ, но вместо того, чтобы изолировать самый старший бит, он округляет до ближайшего целого числа формы 2. н −1 с использованием сдвигов и побитовых операций ИЛИ: [45]

table[0..31] = {0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
                8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31}
function clz4 (x)
    for each y in {1, 2, 4, 8, 16}: x ← x | (x >> y)
    return table[((x * 0x07C4ACDD) >> 27) % 32]

Для процессоров с глубокими конвейерами, таких как Prescott и более поздние процессоры Intel, возможно, будет быстрее заменить ветки побитовыми операторами И и ИЛИ (даже несмотря на то, что требуется гораздо больше инструкций), чтобы избежать очистки конвейера для неправильно предсказанных ветвей (и эти типы ветвей по своей сути являются непредсказуемо):

function clz5 (x)
    r = (x > 0xFFFF) << 4; x >>= r;
    q = (x > 0xFF  ) << 3; x >>= q; r |= q;
    q = (x > 0xF   ) << 2; x >>= q; r |= q;
    q = (x > 0x3   ) << 1; x >>= q; r |= q;
                                    r |= (x >> 1);
    return r;

На платформах, которые обеспечивают аппаратное преобразование целых чисел в числа с плавающей запятой, поле экспоненты можно извлечь и вычесть из константы для вычисления количества ведущих нулей. Исправления необходимы для учета ошибок округления. [41] [46] Преобразование с плавающей запятой может иметь значительную задержку. Этот метод крайне непереносим и обычно не рекомендуется.

int x; 
int r;
union { unsigned int u[2]; double d; } t;

t.u[LE] = 0x43300000;  // LE is 1 for little-endian
t.u[!LE] = x;
t.d -= 4503599627370496.0;
r = (t.u[LE] >> 20) - 0x3FF;  // log2
r++;  // CLZ

Приложения

[ редактировать ]

Операцию подсчета ведущих нулей (clz) можно использовать для эффективной реализации нормализации , которая кодирует целое число как m × 2. и , где m имеет самый старший бит в известной позиции (например, в самой старшей позиции). Это, в свою очередь, можно использовать для реализации деления Ньютона-Рафсона , преобразования целых чисел в числа с плавающей запятой в программном обеспечении и других приложениях. [41] [47]

Подсчет начальных нулей (clz) можно использовать для вычисления 32-битного предиката «x = y» (ноль, если истинно, единица, если ложно) через тождество clz(x − y) >> 5 , где «>>» — беззнаковый сдвиг вправо. [48] Его можно использовать для выполнения более сложных битовых операций, таких как поиск первой строки из n 1 бит. [49] Выражение clz(x − y)1 << (16 − clz(x − 1)/2) — эффективное начальное предположение для вычисления квадратного корня из 32-битного целого числа с использованием метода Ньютона . [50] CLZ может эффективно реализовать подавление нулей — метод быстрого сжатия данных , который кодирует целое число как количество начальных нулевых байтов вместе с ненулевыми байтами. [51] Он также может эффективно генерировать экспоненциально распределенные целые числа, взяв clz равномерно случайных целых чисел. [41]

Логарифмическую базу 2 можно использовать, чтобы предвидеть, произойдет ли переполнение при умножении, поскольку ⌈log 2 (xy)⌉ ≤ ⌈log 2 (x)⌉ + ⌈log 2 (y)⌉ . [52]

Подсчет начальных нулей и подсчет конечных нулей можно использовать вместе для реализации алгоритма обнаружения петель Госпера . [53] который может найти период функции конечного диапазона, используя ограниченные ресурсы. [42]

Алгоритм двоичного НОД тратит много циклов на удаление конечных нулей; это можно заменить счетчиком конечных нулей (ctz), за которым следует сдвиг. Аналогичная петля возникает при вычислении последовательности градин .

Битовый массив может использоваться для реализации приоритетной очереди . В этом контексте поиск первого набора (ffs) полезен для эффективной реализации операции «извлечение» или «извлечение элемента с наивысшим приоритетом». ядра Linux внутренне использует Планировщик реального времени sched_find_first_bit() для этой цели. [54]

Операция подсчета конечных нулей дает простое оптимальное решение проблемы Ханойской башни : диски нумеруются с нуля, и при движении k диск с номером ctz( k ) перемещается на минимально возможное расстояние вправо (оборачиваясь назад к оставлял по необходимости). Он также может генерировать код Грея , взяв произвольное слово и перевернув бит ctz( k ) на шаге k . [42]

См. также

[ редактировать ]

Примечания

[ редактировать ]
  1. ^ Использование битовых операций с машинным словом, отличным от беззнакового, может привести к неопределенным результатам.
  2. ^ Эти четыре операции также имеют (гораздо менее распространенные) отрицательные версии:
    • найти первый ноль ( ffz ), который идентифицирует индекс младшего нулевого бита;
    • count замыкающие единицы , который подсчитывает количество единиц, следующих за младшим нулевым битом.
    • countведущие , который подсчитывает количество единиц, предшествующих самому старшему нулевому биту;
    • найти индекс старшего нулевого бита, который является инвертированной версией двоичного логарифма .
  1. ^ Андерсон . Найдите логарифмическую базу 2 целого числа со старшим битом N, установленным за операции O (N) (очевидный способ) .
  2. ^ Перейти обратно: а б «ФФС(3)» . Руководство программиста Linux . Архивы ядра Linux . Проверено 2 января 2012 г.
  3. ^ «Справочник инструкций ARM > Общие инструкции по обработке данных ARM > CLZ» . Руководство по ассемблеру ARM Developer Suite . РУКА . Проверено 03 января 2012 г.
  4. ^ «Документ по архитектуре AVR32» (PDF) (изд. CORP072610). Корпорация Атмел . 2011. 32000D–04/201. Архивировано из оригинала (PDF) 25 октября 2017 г. Проверено 22 октября 2016 г.
  5. ^ Перейти обратно: а б Справочное руководство по архитектуре Alpha (PDF) . Компак . 2002. стр. 4–32, 4–34.
  6. ^ Перейти обратно: а б Руководство разработчика программного обеспечения для архитектур Intel 64 и IA-32 . Том. 2А. Интел . стр. 3-92–3-97. Номер заказа 325383.
  7. ^ Руководство программиста по архитектуре AMD64, том 3: Общие инструкции и системные инструкции (PDF) . Том. 3. Усовершенствованные микроустройства (AMD). 2011. С. 204–205. Публикация № 24594.
  8. ^ «Руководство программиста по архитектуре AMD64, том 3: универсальные и системные инструкции» (PDF) . Технология AMD64 (изд. версии 3.28). Передовые микроустройства (AMD). Сентябрь 2019 г. [2013 г.]. Публикация № 24594. Архивировано (PDF) из оригинала 30 сентября 2019 г. Проверено 2 января 2014 г.
  9. ^ Руководство разработчика программного обеспечения для архитектуры Intel Itanium. Том 3: Набор инструкций Intel Itanium . Том. 3. Интел . 2010. стр. 3:38. Архивировано из оригинала 26 июня 2019 г.
  10. ^ Перейти обратно: а б Архитектура MIPS для программистов. Том II-A: Набор инструкций MIPS32 (редакция 3.02). МИПС Технологии . 2011. С. 101–102. Архивировано из оригинала 07.11.2017 . Проверено 4 января 2012 г.
  11. ^ Перейти обратно: а б Архитектура MIPS для программистов. Том II-A: Набор инструкций MIPS64 (редакция 3.02). МИПС Технологии . 2011. С. 105, 107, 122, 123.
  12. ^ Справочное руководство программиста семейства M68000 (включая инструкции CPU32) (PDF) (первая редакция). Моторола . 1992. стр. 4-43–4-45. М68000ПРМ/АД. Архивировано из оригинала (PDF) 8 декабря 2019 г.
  13. ^ Фрей, Брэд. «Глава 3.3.11 Логические инструкции с фиксированной точкой». Книга по архитектуре PowerPC (изд. версии 2.02). ИБМ . п. 70.
  14. ^ «Глава 3.3.13 Логические инструкции с фиксированной точкой - Глава 3.3.13.1 64-битные логические инструкции с фиксированной точкой». Power ISA версии 3.0B . ИБМ . стр. 95, 98.
  15. ^ Перейти обратно: а б Вольф, Клиффорд (22 марта 2019 г.). «Расширение битовых манипуляций RISC-V «B» для RISC-V» (PDF) . Github (Черновик) (изд. v0.37) . Проверено 9 января 2020 г.
  16. ^ Архитектура Oracle SPARC 2011 . Оракул . 2011.
  17. ^ Справочное руководство по архитектуре VAX (PDF) . Корпорация цифрового оборудования (DEC). 1987. стр. 70–71. Архивировано (PDF) из оригинала 29 сентября 2019 г. Проверено 9 января 2020 г.
  18. ^ Перейти обратно: а б с «Глава 22. Векторные целочисленные инструкции». Принципы работы IBM z/Architecture (PDF) (одиннадцатое изд.). ИБМ . Март 2015 г., стр. 7-219–22-10. SA22-7832-10. Архивировано из оригинала (PDF) 9 января 2020 г. Проверено 10 января 2020 г.
  19. ^ Перейти обратно: а б «ФФС(3)» . Библиотека разработчиков Mac OS X. Apple, Inc., 19 апреля 1994 г. Проверено 4 января 2012 г.
  20. ^ «ФФС(3)» . Руководство по функциям библиотеки FreeBSD . Проект FreeBSD . Проверено 4 января 2012 г.
  21. ^ «Другие встроенные функции, предоставляемые GCC» . Использование коллекции компиляторов GNU (GCC) . Free Software Foundation, Inc. Проверено 14 ноября 2015 г.
  22. ^ «Журнал изменений GCC 3.4.0» . GCC 3.4.0 . Free Software Foundation, Inc. Проверено 14 ноября 2015 г.
  23. ^ «Расширения языка Clang — глава Встроенные функции» . Команда Клана . Проверено 9 апреля 2017 г. Clang поддерживает ряд встроенных библиотечных функций с тем же синтаксисом, что и GCC.
  24. ^ «Исходный код Clang» . Команда LLVM, Университет Иллинойса в Урбана-Шампейн . Проверено 9 апреля 2017 г.
  25. ^ «_BitScanForward, _BitScanForward64» . Visual Studio 2008: Visual C++: встроенные функции компилятора . Майкрософт . Проверено 21 мая 2018 г.
  26. ^ «_BitScanReverse, _BitScanReverse64» . Visual Studio 2008: Visual C++: встроенные функции компилятора . Майкрософт . Проверено 21 мая 2018 г.
  27. ^ «__lzcnt16, __lzcnt, __lzcnt64» . Visual Studio 2008: Visual C++: встроенные функции компилятора . Майкрософт . Проверено 03 января 2012 г.
  28. ^ «Внутренности ARM» . Visual Studio 2012: Visual C++: внутренние функции компилятора . Майкрософт . Проверено 9 мая 2022 г.
  29. ^ «Руководство по внутренним компонентам Intel» . Интел . Проверено 03 апреля 2020 г.
  30. ^ Справочник по внутренним компонентам компилятора Intel C++ для Linux . Интел . 2006. с. 21.
  31. ^ Руководство по программированию NVIDIA CUDA (PDF) (изд. версии 3.0). NVIDIA . 2010. с. 92.
  32. ^ « 'llvm.ctlz.*' Внутренний, 'llvm.cttz.*' Внутренний» . Справочное руководство по языку LLVM . Инфраструктура компилятора LLVM . Проверено 23 февраля 2016 г.
  33. ^ Смит, Ричард (01 апреля 2020 г.). N4861 Рабочий проект стандарта языка программирования C++ (PDF) . ИСО/МЭК. стр. 1150–1153 . Проверено 25 мая 2020 г.
  34. ^ «Заголовок стандартной библиотеки <бит>» . cppreference.com . Проверено 25 мая 2020 г.
  35. ^ Перейти обратно: а б SPARC International, Inc. (1992). «A.41: Подсчет населения. Примечание по программированию» (PDF) . Руководство по архитектуре SPARC: версия 8 (изд. версии 8). Энглвуд Клиффс, Нью-Джерси, США: Прентис Холл . стр. 231 . ISBN  978-0-13-825001-0 .
  36. ^ Уоррен-младший, Генри С. (2013) [2002]. Хакерское наслаждение (2-е изд.). Аддисон Уэсли - Pearson Education, Inc. ISBN  978-0-321-84268-8 . 0-321-84268-5.
  37. ^ Справочник по набору инструкций Blackfin (предварительная редакция). Аналоговые устройства . 2001. стр. 8–24. Номер детали 82-000410-14.
  38. ^ Дитц, Генри Гордон . «Агрегатные магические алгоритмы» . Университет Кентукки . Архивировано из оригинала 31 октября 2019 г.
  39. ^ Айзенберг, Герд (03.11.2019) [2012]. «БитСканЗащита» . Wiki по шахматному программированию (CPW) . Архивировано из оригинала 9 января 2020 г. Проверено 9 января 2020 г.
  40. ^ Андерсон . Округляем до следующей наибольшей степени 2 .
  41. ^ Перейти обратно: а б с д Уоррен . Глава 5-3: Подсчет ведущих нулей.
  42. ^ Перейти обратно: а б с Уоррен . Глава 5-4: Подсчет конечных нулей.
  43. ^ Лейзерсон, Чарльз Э .; Прокоп, Харальд ; Рэндалл, Кейт Х. (7 июля 1998 г.). «Использование последовательностей де Брёйна для индексации единицы в компьютерном слове» (PDF) . Лаборатория компьютерных наук Массачусетского технологического института, Кембридж, Массачусетс, США. Архивировано (PDF) из оригинала 9 января 2020 г. Проверено 9 января 2020 г.
  44. ^ Буш, Филип (01 марта 2009 г.) [21 февраля 2009 г.]. «Практическое руководство по вычислению конечных нулей» (PDF) . Архивировано (PDF) из оригинала 1 августа 2016 г. Проверено 9 января 2020 г.
  45. ^ Андерсон . Найдите логарифмическую базу 2 N-битного целого числа за операции O(lg(N)) с помощью умножения и поиска .
  46. ^ Андерсон . Найдите логарифм целого числа по основанию 2 для целого числа с 64-битным числом с плавающей запятой IEEE .
  47. ^ Слосс, Эндрю Н.; Саймс, Доминик; Райт, Крис (2004). Руководство разработчика систем ARM по проектированию и оптимизации системного программного обеспечения (1-е изд.). Сан-Франциско, Калифорния, США: Морган Кауфманн . стр. 212–213. ISBN  978-1-55860-874-0 .
  48. ^ Уоррен . Глава 2-11: Предикаты сравнения.
  49. ^ Уоррен . Глава 6-2: Найдите первую строку из 1 бит заданной длины.
  50. ^ Уоррен . Глава 11-1: Целочисленный квадратный корень.
  51. ^ Шлегель, Бенджамин; Гемулла, Райнер; Ленер, Вольфганг [на немецком языке] (июнь 2010 г.). «Быстрое целочисленное сжатие с использованием инструкций SIMD». Материалы шестого международного семинара по управлению данными на новом оборудовании . стр. 34–40. CiteSeerX   10.1.1.230.6379 . дои : 10.1145/1869389.1869394 . ISBN  978-1-45030189-3 . S2CID   7545142 .
  52. ^ Уоррен . Глава 2-12: Обнаружение переполнения.
  53. ^ Госпер, Билл (апрель 1995 г.) [1972-02-29]. Бейкер, Генри Гивенс младший (ред.). «Петлевой детектор» . ХАКМЕМ (перепечатанное и преобразованное издание). Кембридж, Массачусетс, США: Лаборатория искусственного интеллекта Массачусетского технологического института (MIT). AI Memo 239 Пункт 132. Архивировано из оригинала 08 октября 2019 г. Проверено 9 января 2020 г.
  54. ^ Аас, Джош (17 февраля 2005 г.). Общие сведения о планировщике ЦП Linux 2.6.8.1 (PDF) . Силикон Графика, Инк. (SGI). п. 19. Архивировано (PDF) из оригинала 19 мая 2017 г. Проверено 9 января 2020 г.

Дальнейшее чтение

[ редактировать ]
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: fb0cd5a946f0e071169ea965eb803368__1717854000
URL1:https://arc.ask3.ru/arc/aa/fb/68/fb0cd5a946f0e071169ea965eb803368.html
Заголовок, (Title) документа по адресу, URL1:
Find first set - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)