- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在遍历树来构建霍夫曼前缀代码LUT。我正在使用寄存器来跟踪当前前缀。
我退出分析树的算法的条件使用以下条件,必须为true:
树中的当前元素必须是叶子
当前的前缀代码将所有位设置为无假位。
对于第二个条件,我还跟踪前缀字符串的当前长度(以位为单位)。
如何测试寄存器的位设置是否超过1位,并且所有设置位彼此相邻?
编辑:设置位组必须从位0开始并且与前缀长度一样长(存储在另一个寄存器中)
最佳答案
构造单元将是:在连续组的低位加1将清除所有这些位并带进位,而在该组上方保留1位。例如0xff +1 = 0x100。
如果未设置任何位,则进位将不会一直传播,例如0b01101 + 1 = 0b01110
,未设置位#4。 (并且不保留某些现有设置位的翻转,因此x & (x+1)
为true。)
这适用于寄存器底部(加1)或更高位置的位组(用(-x) & x
隔离最低的设置位并添加它,例如用BMI1 blsi
或mov / neg / and)。
一个相关的bithack是y & (y-1)
测试,该整数仅设置一个位(通过清除最低的设置位)来设置整数:https://graphics.stanford.edu/~seander/bithacks.html#DetermineIfPowerOf2。但是,由于我们使用y
生成x+1
,因此我们可以将其优化到x & (x+1)
以检测寄存器底部的连续掩码。
您的情况很简单:
位范围的底部必须为位0
位范围恰好是n
位宽(前缀长度)
这些限制意味着恰好有1个整数可以同时满足这两个要求,因此您应该对其进行预先计算,并简单地与cmp/je
比较是否相等。底部设置n
位的数字为prefix_mask = (1<<n) - 1
。减法的进位(借位)将所有位设置为低于该隔离的高位,并清除原始位。高于该位的位保持不变,因为该高位满足了借入要求。
给定前缀长度n
,您可以使用1<<n
(在Intel CPU上为单-uop,在AMD为https://agner.org/optimize/上为2 oups)来计算bts
。
;; input: prefix length in EDX
;; output: prefix mask in ESI
xor esi, esi
bts esi, edx ; set bit n; eax |= 1<<n
dec esi ; set all the bits BELOW that power of 2
; then later, inside a loop: input in EAX
cmp eax, esi
je all_bits_set_up_to_prefix
cmp [rsp+16], edx
代替静态LUT,同时使用相同的前缀长度循环。
lea edx, [eax+1]
/
bsr edx,edx
将掩码转换回前缀长度,以找到
mask+1
的最高设置位的位索引。 (或者,如果前缀长度可以为32,但不能为零,则
bsr
/
inc
。输入值为0的
BSR保留目标不变,并设置ZF。AMD对此进行了说明,Intel的文档说“ undefined”,但其当前HW确实使目标保持不变,这就是指令对输出具有“ false”依赖性的原因。)
n
位全为1,而EDN的无损检测,位#n本身为0。(如果是这种情况,则加1清除低位并设置位
n
)。如果以后没有用处,可以使用
inc edx
代替LEA进行复制和添加。
;;; check the low n bits, ignoring whether higher bits are set or not
;;; inputs: prefix length in ECX, candidate in EDX
lea eax, [rdx+1]
bt eax, ecx
;;; output: CF = 1 if all the bits from 0..len-1 were set, else 0
test
指令,它将与
jcc
宏融合,因此在Intel CPU上,这不会花费任何额外的指令。 。在
btr
为2 oups而
bt
为1的AMD CPU上,这会额外增加1 uop。 (test / jcc可以在AMD Bulldozer系列及更高版本上融合。)
;;; input: prefix length in ECX, candidate in EDX
lea eax, [rdx+1] ; produces a single set bit?
btr eax, ecx ; reset that bit, leaving eax=0 if no other bits were set
test eax, eax ; compare against zero
;;; output: ZF=1 (and eax=0) if EDX == (1<<ECX)-1 with no higher bits set.
jz contiguous_bitmask_of_length_ecx
x & (x+1)
在寄存器的底部检查未知长度的单个连续位组,该组确实会检测是否设置了更高的位。如果有一个高位未被进位传播所翻转,则AND或TEST将产生非零结果。
0
和
1
与像
0b0111
这样的多位组相同。在此测试之前,您可能需要
cmp eax, 3
/
jb not_multibit_prefix
。
; check for a contiguous bit-group at the bottom of a reg of arbitrary length, including 0
;;; input: candidate in EDX
lea eax, [rdx+1] ; carry-out clears all the set bits at the bottom
test eax, edx ; set flags from x & (x+1)
;;; output: ZF=1 if the only set bits in EDX were a contiguous group at the bottom
lea eax, [rdx+1]
/
test eax, edx
(ZF = 1:仅设置了连续的低位)/
bt eax, ecx
(CF = 1:它结束于我们想要的位置)的怪异部分标志。但是x86没有需要CF = 1和ZF = 1的
jcc
condition。如果使用
ja
,则使用
(CF=0 and ZF=0)
;如果使用
jbe
,则使用
(CF=1 or ZF=1)
,因此两者均无效。当然,如果没有有效的部分标志合并,这在CPU上将是可怕的,从而导致部分标志停顿。
(-x) & x
隔离最低的设置位。 BMI1为此添加了一条指令
blsi
。因此,如果可以假设支持BMI1,则可以1 uop进行无损检测。否则需要3。
unsigned bits_contiguous(unsigned x) {
unsigned lowest_set = (-x) & x; // isolate lowest set bit
unsigned add = x + lowest_set; // carry flips all the contiguous set bits
return (add & x) == 0; // did add+carry leave any bits un-flipped?
}
test
/
setcc
,所以我们可以看看他们为创建正确的整数所做的工作标志条件。
#define TEST(n) int test##n(){return bits_contiguous(n);}
的某些编译时常量的逻辑正确(并查看asm是
xor eax,eax
还是
mov eax,1
)。请参见
C + asm on the Godbolt compiler explorer。一些有趣的情况是
TEST(0)
= 1,因为该条件基本上检查是否存在多个位组。 (因此,对于此检查,零位组与1位组相同。)
TEST(0xFFFFFFFF)
= 1:具有
x+1 = 0
也不是问题。
# gcc8.3 -O3 -march=haswell (enables BMI1 and BMI2)
bits_contiguous:
blsi eax, edi
add eax, edi
test eax, edi # x & (x+lowest_set)
sete al
movzx eax, al
ret
blsi
,我们需要3条指令,而不是1条指令:
mov eax, edi
neg eax
and eax, edi # eax = isolate_lowest(x)
add eax, edi
test eax, edi
popcnt
以确保设置了正确的位数(并分别检查它们是否连续)。 Popcnt不是基线,Nehalem之前的CPU没有它,并且如果尝试运行它会出错。
;input: prefix len in ECX, candidate in EDX
;clobbers: EAX
popcnt eax, edx
cmp eax, ecx
jne wrong_number_of_bits_set ; skip the contiguousness test
blsi eax, edi
add eax, edi
test eax, edi # x & (x+lowest_set)
jz contiguous_bitgroup_of_length_ecx
wrong_number_of_bits_set:
关于assembly - 测试所有真实位是否相邻,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55327117/
我想在数组中找到连接(相邻)的元素。 例如,在数组中: [1,2,3,4,5] 要访问所有 2 个连通元素,输出将为: 1,2 2,3 3,4 4,5 要访问所有 3 个连通元素,输出将为 1,2,3
我有三个 Sprite ,彼此堆叠在一起。 我修改了他们的 transform.matrix 以给出他们一致增长的外观。 但是,根据比例因子,瓷砖之间有时会出现小裂缝。 cracks between
我正在阅读有关 Margin Collapsing 的文章,我遇到了这个:margin Adjacent siblings The margins of adjacent siblings are c
float div 的框阴影被其右侧的邻居截断,但左侧未截断。 我玩过 z-index 和 overflow: visible,但没有用。 HTML: CSS: .doc-page {
我有多个元素说卡片。这些卡片需要水平堆叠并且高度需要相同。这正在发生在我身上。 每张卡片都有图像、文本和按钮。每张卡片的图像和文本应采用任何卡片中的最大高度,以便它们正确对齐。这不会发生在我身上。 如
我有这个 GUI 我使用了 GridBagLayout,但我不知道为什么 Plain Bread 复选框与其相应的标签之间有很大的间距。 而且,我尝试仅增加按钮沿 x 轴的间距,但尽管重置了插图,但沿
在过去,我已经为自定义元素符号使用了数百次列表项背景图像,但不知何故从未遇到过这个问题。 基本上,我有一个 IMG float 在无序列表的左侧。元素符号背景图像设置在每个 LI 的左上角。但是, f
我正在使用 Bootstrap 框架并使用 2 列网格。 html 内容有标题、链接、副标题和文本。这增加了该列的高度。我希望它旁边的列与其高度匹配(以便图像显示)没有设置高度图像不显
我有一个 php 代码可以生成数百个 和 标签。我的问题如下,我有以下内容: X X 我想要第二个的边框颜色更重要,以便共享边框显示为灰色而不是黑色。我可以在第二个 td 中使用重要性或继承标签吗?
Place holder for Radio1 Place holder for Radio2 在此,我只想要 与相应的单选按钮相关联是可见的,但是...... * { visibilit
我正在尝试在 html 中实现以下布局。更大的 div 1。然后是它旁边的另一个 div,顶部有一个边距。如果我给 float: left 给第一个 div,给第二个 div margin-top 也
假设我有 2 个名为 IN 和 MASK 的二进制输入。实际字段大小可能是 32 到 256 位,具体取决于用于完成任务的指令集。两个输入都会改变每次调用。 Inputs: IN = ...110
我想知道是否有一种简洁/一行的方法来执行以下操作: pack :: [a] -> [(a, a)] pack [] = [] pack [_] = [] pack (x:y:xs
下面的代码分为两部分,一部分处理头部的管理,另一部分处理“主体”,当我执行代码时引发下面的异常,我该如何解决该错误?我不知道下面的错误是什么原因造成的,错误是在react的解析上 错误: Line
http://imgur.com/a/DA5i4 在上面的两张图片中你可以看到我有一个主容器,里面装满了 3 个较小的 div,一个大的在中间,两个瘦的在两边,但是右边直到中间的 div 下面才开始。
正如我在标题中解释的所有内容,然后我将只为你们提供我现在拥有的代码,我一直在努力实现我想要的东西很长时间但没有运气......它表现得像响应式的,但即使调整大小我也想将其保持在原位...截图
我编写了一个 jquery 插件,它使用 Flot 将 HTML 表格转换为图表。 HTML 是从 XSLT 生成的,在 XSLT 中我有以下代码来调用我的插件。此代码尝试在 blah1 和 blah
我正在尝试实现这样的布局。 aaa xxxxxx oooo aaa xxxxxx oooo xxxxxx xxxxxx bbb xxxxxx cccc bbb xxxxxx cc
在包含网格的 2 个 div 上使用内联 css 显示不起作用 最佳答案 为您的 div 指定宽度并根据您的要求使用“float: left”或“right”。不要对 div 使用“内联” 例如 CS
我将 MVC 项目中的一些代码返回到网页。我无法用撇号解决问题,当我的电话看起来像这样时,我如何忽略它 document.getElementById('some').insertAdjacentHT
我是一名优秀的程序员,十分优秀!