- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
请考虑以下英特尔8086汇编程序:
CX保持非零值。
L: ADD AX, AX
ADC DX, 0
LOOP L
SHL AX, CX
最佳答案
您对当前代码的工作方式的理解基本上是正确的。为了确保我们理解它,让我们逐步执行一个示例执行。通常,这种事情可以通过调试器来完成,但是我们真正需要的只是我们的头部和一个可以显示二进制值的计算器。
假设AX
为55312(选择较大的初始值可使我们立即看到进位的影响)。 CX
将为4,当然DX
已预先清零。
迭代1:55312 + 55312
溢出16位值的范围,因此将进位设置为1,现在AX
为45088。由于设置了进位,因此DX
=1。CX
减为3。
迭代2:45088 + 45088
再次溢出,因此进位被设置,并且AX
现在为24640。DX
= 2; CX
= 2。
迭代3:24640 + 24640
不会溢出,因此未设置进位,因此AX
现在为49280。DX
= 2; CX
= 1。
迭代4:49280 + 4928
溢出,因此进位被设置,并且AX
现在为33024。DX
= 3; CX
= 0。
因此,当我们完成时,DX
为3。如果我们看一下起始值的二进制表示形式:
1101 1000 0001 0000
↑ ↑
bit 15 bit 0
CX
)中的置位(1)位的数目为3,等于
DX
。
AX
是输入值,而
CX
包含迭代次数:
CX
中的高位
AX
位,丢弃其余部分。
AX
中的设置位数。
SHR
右移,然后使用
POPCNT
指令对所需位数中的设置位数进行计数就很简单了。范围。例如:
; AX == input value
; CX == number of iterations
neg cx
add cx, 16 ; cx = 16 - cx
shr ax, cl ; ax = ax << cx
popcnt ax, ax ; ax = # of 1 bits in ax
POPCNT
指令的较旧的CPU,该怎么办?好吧,您需要模拟它。有多种快速方法可以实现人口计数/汉明权重算法。在奔腾或更高版本上,最快的方法是:
; AX == input value
; CX == number of iterations
neg cx
add cx, 16 ; cx = 16 - cx
shr ax, cl ; ax = ax << cx
; emulate popcnt
mov dx, ax
shr dx, 1
and dx, 21845
sub ax, dx
mov cx, ax
and ax, 13107
shr cx, 2
and cx, 13107
add cx, ax
mov dx, cx
shr dx, 4
add dx, cx
and dx, 3855
mov ax, dx
shr ax, 8
add ax, dx
and ax, 63
XLAT
指令是迄今为止在表中查找值的最快方法:
LUT DB 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
; AX == input value
; CX == number of iterations
neg cx
add cx, 16 ; cx = 16 - cx
shr ax, cl ; ax = ax << cx
; emulate popcnt using LUT
mov bx, OFFSET LUT
xlat ; equivalent to: mov al, [bx + al]
xchg al, ah
xlat ; equivalent to: mov al, [bx + al]
add al, ah
xor ah, ah
neg cx ; 3 cycles
add cx, 16 ; 4 cycles
shr ax, cl ; 8+(4*CL) cycles
mov bx, OFFSET LUT ; 4 cycles
xlat ; 11 cycles
xchg al, ah ; 4 cycles
xlat ; 11 cycles
add al, ah ; 3 cycles
xor ah, ah ; 3 cycles
;-----------------
; 51+(4*CL) cycles
CL
中)还要加上4个额外的周期。不幸的是,我们对此无能为力。这意味着我们的最佳情况性能约为50个周期,最坏情况的性能仍低于120个周期。
xor dx, dx ; 3 cycles
L: add ax, ax ; 3 cycles
adc dx, 0 ; 4 cycles
loop L ; taken: 17 cycles; not-taken: 5 cycles
;---------------------------------------
; 8+(24*CL) cycles
CX
(循环计数),因为它确定分支被采用的次数。因此,在最佳情况下,此代码大约需要32个周期。在最坏的情况下,大约需要400个周期。
CX
很小的情况下),但是我们基于LUT的经过优化的,基于位计数的方法具有更好的最坏情况性能,更重要的是,它可以扩展更好。您可以通过以下两种方法的图形比较清楚地看到这一点:
CX
小,您的原始代码就是一个合理的实现。但是随着
CX
的增大,由于所有这些
LOOP
,例程变得越来越慢。我们基于LUT的方法具有更大的开销(这还没有算上LUT加到二进制文件中的膨胀),但是随着
CX
的变大,它才真正开始得到回报。总之,我们已经将增加的代码大小用于执行速度,这是常见的优化折衷方案。
CX
永远不会大于16。如果
CX
大于16,我一直向您展示的所有“优化”代码都将无法工作,因为
SHR
指令将尝试移出太多位。如果需要处理
CX
> 16,则需要调整代码,以将
CX
限制为小于或等于16。这意味着有条件分支或一系列巧妙的位-旋转指令,这两种指令都会增加代码的复杂性并增加其周期数。换句话说,这将增加“优化”方法的基准开销,但是此方法将比原始方法继续更好地扩展。图形上,红线将向上平移。
CX
值,而不会产生任何额外的损失,因为它只会保持
LOOP
。但是,正如我们已经看到的那样,每一个都会付出重大的性能损失。这些
LOOP
中的一个。)
LUT DB 0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,2,3,3,4,3,4,4,5,3,4,4,5,4,5,5,6,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,3,4,4,5,4,5,5,6,4,5,5,6,5,6,6,7,4,5,5,6,5,6,6,7,5,6,6,7,6,7,7,8
; AX == input value
; CX == number of iterations
mov bx, 16 ; 4 cycles
cmp cx, bx ; cx < 16? ; 3 cycles
jae SkipShift ; 4 cycles (fall-through); 16 cycles (branch)
sub bx, cx ; 3 cycles
mov cx, bx ; cx -= 16 ; 2 cycles
shr ax, cl ; ax <<= cx ; 8+(4*CL) cycles
SkipShift:
mov bx, OFFSET LUT ; 4 cycles
xlat ; 11 cycles
xchg al, ah ; 4 cycles
xlat ; 11 cycles
add al, ah ; 3 cycles
xor ah, ah ; 3 cycles
JAE
,您将要支付16个周期的罚款,但是在这种情况下,我们可以跳过减法和平移,以弥补那些丢失的周期。如果不采用
JAE
,并且执行失败,那么我们只会丢失4个周期。总体而言,最佳情况下的性能约为60个周期,而最坏情况下的性能约为慢速的两倍。
关于performance - 保存左移(SHL)中偏移的位,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44637692/
我正在尝试从第 4 到 9 页以及第 12 和 13 页上的单元格中清除所有内容(包括图像)。我有以下代码,但它正在清除第 3-9 和 12-15 页中的内容,我不知道为什么。 有什么想法吗? Sub
有没有办法增加极坐标图刻度标签(θ)的填充/偏移? import matplotlib import numpy as np from matplotlib.pyplot import figure,
我正在调用本地 API 并尝试以分页 样式进行操作。我有 n 张图片,我想将它们分成 n/4 行(每行 4 张图片)。因此,我正在调用我的 API,images/count,offset。但不知何故,
我的问题解释起来有点棘手,但无论如何我都会尝试。我有两个水平选项卡,当您单击它们时,会打开一个文本框内容。当他们被点击时,我试图“关注”他们。我在网上找到了很多资料,但除了我在下面显示的这段代码外,没
所以我有一个 float 的 div,我需要它始终向右 200 像素,并填充窗口的其余部分。有没有某种跨浏览器兼容的方法,我可以在不借助 javascript 的情况下使宽度填满页面的其余部分? 最佳
我有以下片段 $('html,body').animate({scrollTop: $('#menu').offset().top}, 'slow'); 单击链接时,我希望浏览器从#menu div
我目前正在为我的应用程序使用 JASidePanel,并且我有一个 UITableViewcontroller 和一个 UIRefreshControl 作为它的 ViewController 之一。
给出以下代码: imshow(np.arange(16*16).reshape(16,16)) cb = colorbar() cb.set_label("Foo") cb.set_ticks([0,
我是编程新手,我认为 VBA 是一个很好的起点,因为我在 Excel 中做了很多工作。 我创建了一个宏,它从输入框中获取一个整数(我一直使用 2、3 和 4 来测试),并创建该数字的一组 4 层层次结
我在 PHP 中有一个 unix 时间戳: $timestamp = 1346300336; 然后我有一个我想要应用的时区的偏移量。基本上,我想应用偏移量并返回一个新的 unix 时间戳。偏移量遵循这
演示:http://jsfiddle.net/H45uY/6/ 我在这里想做的是将 的左上角设为跟随鼠标。代码在没有段落的情况下工作正常(请参阅上面的演示),但是当您添加段落时,被向上推,鼠标位于盒
假设我们有两个由无符号长(64 位)数组表示的位图。我想使用特定的移位(偏移)合并这两个位图。例如,将位图 1(较大)合并到位图 2(较小)中,起始偏移量为 3。偏移量 3 表示位图 1 的第 3 位
通过在 pageViewController 中实现 tableView,tableView 与其显示的内容不一致。对此最好的解决办法是什么? 最佳答案 如果您的 TableView 是 View C
我设置了一个在 nib 中显示地点信息的地点配置文件。当我在标准屏幕流程中推送此 View 时,它工作正常。但是,当我从另一个选项卡推送此 View 时,UINavigationBar 似乎抵消了它,
如果我想选择 5 条记录,我会这样做: SELECT * FROM mytable LIMIT 5 如果我想添加偏移量,我会这样做: SELECT * FROM mytable OFFSET 5 LI
我有一个应用程序,其中某些 View 需要全屏,而其他 View 不需要全屏。在某些情况下,我希望背景显示在状态栏下方,所以我在 View 加载时使用它来使 Activity 全屏显示: window
在下图中,我进行绘制,结果位于 A 点,就在我手指接触的地方。 如何使图像显示在实际触摸上方约 40pt。 (二) 我正在使用经典的 coreGraphic UITouch 代码,如下所示: - (v
只要键盘处于事件状态,我就会尝试偏移 UITextField,效果很好,直到我尝试了表情符号布局。有没有办法检测键盘输入的类型,以便找出高度差?谢谢 最佳答案 不是使用 UIKeyboardDidSh
这是我的 Swift 代码 (AppDelegate.swift): var window: UIWindow? var rootViewController :UIViewController? f
我有一个 div 作为绝对定位的 body 的直接子节点,其 css 属性定义如下: div[id^="Container"] { display: block; position: a
我是一名优秀的程序员,十分优秀!