相关疑难解决方法(0)

什么是按位移位(位移)运算符以及它们如何工作?

我一直在尝试在业余时间学习C语言,其他语言(C#,Java等)具有相同的概念(通常是相同的运算符)......

我想知道是,在核心层,是什么位移(<<,>>,>>>)这样做,可以帮助它什么问题解决,和周围的弯曲什么潜伏的陷阱?换句话说,一个绝对的初学者指导比特移位的所有优点.

bit-manipulation binary-operators operators bit-shift

1340
推荐指数
9
解决办法
67万
查看次数

用于测试Collat​​z猜想的C++代码比手写程序集更快 - 为什么?

我为Project Euler Q14编写了这两个解决方案,在汇编和C++中.它们是用于测试Collat​​z猜想的相同蛮力方法.装配解决方案与组装

nasm -felf64 p14.asm && gcc p14.o -o p14
Run Code Online (Sandbox Code Playgroud)

C++是用.编译的

g++ p14.cpp -o p14
Run Code Online (Sandbox Code Playgroud)

部件, p14.asm

section .data
    fmt db "%d", 10, 0

global main
extern printf

section .text

main:
    mov rcx, 1000000
    xor rdi, rdi        ; max i
    xor rsi, rsi        ; i

l1:
    dec rcx
    xor r10, r10        ; count
    mov rax, rcx

l2:
    test rax, 1
    jpe even

    mov rbx, 3
    mul rbx
    inc rax
    jmp c1

even:
    mov rbx, 2 …
Run Code Online (Sandbox Code Playgroud)

c++ optimization performance x86 assembly

803
推荐指数
8
解决办法
14万
查看次数

C++中循环移位(旋转)操作的最佳实践

左右移位运算符(<<和>>)已在C++中可用.但是,我无法找到如何执行循环移位或旋转操作.

如何执行"向左旋转"和"向右旋转"等操作?

在这里向右旋转两次

Initial --> 1000 0011 0100 0010
Run Code Online (Sandbox Code Playgroud)

应该导致:

Final   --> 1010 0000 1101 0000
Run Code Online (Sandbox Code Playgroud)

一个例子会有所帮助.

(编者注:如果旋转计数为零,许多常见的表达方式在C中旋转会受到未定义的行为的影响,或者编译为不止一个旋转机器指令.这个问题的答案应记录最佳实践.)

c c++ bit-manipulation c++-faq rotation

84
推荐指数
9
解决办法
10万
查看次数

INC指令与ADD 1:重要吗?

来自Ira Baxter回答,为什么INC和DEC指令不会影响进位标志(CF)?

大多数情况下,我远离INCDEC现在,因为他们做的部分条件代码更新,这样就可以在管道中引起滑稽的摊位,和ADD/ SUB没有.因此,无关紧要(大多数地方),我使用ADD/ SUB避免失速.我使用INC/ DEC仅在保持代码较小的情况下,例如,适合高速缓存行,其中一个或两个指令的大小产生足够的差异.这可能是毫无意义的纳米[字面意思!] - 优化,但我在编码习惯上相当老派.

我想问一下为什么它会导致管道中的停顿,而添加不会?毕竟,无论是ADDINC更新标志寄存器.唯一的区别是INC不更新CF.但为什么重要呢?

performance x86 assembly increment micro-optimization

26
推荐指数
2
解决办法
4234
查看次数

x86的MOV真的可以"免费"吗?为什么我不能重现这个呢?

我一直看到人们声称MOV指令可以在x86中免费,因为寄存器重命名.

对于我的生活,我无法在一个测试用例中验证这一点.每个测试用例我尝试揭穿它.

例如,这是我用Visual C++编译的代码:

#include <limits.h>
#include <stdio.h>
#include <time.h>

int main(void)
{
    unsigned int k, l, j;
    clock_t tstart = clock();
    for (k = 0, j = 0, l = 0; j < UINT_MAX; ++j)
    {
        ++k;
        k = j;     // <-- comment out this line to remove the MOV instruction
        l += j;
    }
    fprintf(stderr, "%d ms\n", (int)((clock() - tstart) * 1000 / CLOCKS_PER_SEC));
    fflush(stderr);
    return (int)(k + j + l);
}
Run Code Online (Sandbox Code Playgroud)

这为循环生成以下汇编代码(随意生成这个你想要的;你显然不需要Visual C++):

LOOP:
    add edi,esi
    mov …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly cpu-registers micro-optimization

23
推荐指数
2
解决办法
2113
查看次数

Is a logical right shift by a power of 2 faster in AVR?

I would like to know if performing a logical right shift is faster when shifting by a power of 2

For example, is

myUnsigned >> 4
Run Code Online (Sandbox Code Playgroud)

any faster than

myUnsigned >> 3
Run Code Online (Sandbox Code Playgroud)

我很欣赏每个人的第一反应是告诉我,人们不应该担心像这样的小事,它使用正确的算法和集合来减少重要的数量级.我完全同意你的意见,但我真的想从嵌入式芯片(ATMega328)中挤出所有东西 - 我只是有一个性能转变,值得'哇喔!' 通过用位移替换除法,所以我向你保证这很重要.

c++ optimization avr atmega bit-shift

7
推荐指数
2
解决办法
5293
查看次数

Java中的整数用于哪个位

我编写了这段代码来检查Java中Integer(如果用二进制表示)的哪些位是打开的:

public static List<String> list(int val)
{
    List<String> dummyList = new ArrayList<String>();

    int bit = 1;
    int x;

    for(int i=0; i<32; i++)
    {
        x = bit;
        if((x&val)!=0)
            dummyList.add(String.valueOf(i+1));
        bit = bit << 1;
    }

    return dummyList;
}
Run Code Online (Sandbox Code Playgroud)

上面编写的代码工作正常.但是它有一个运行32次的循环(在Java整数中是32位长).我想尽量减少这种复杂性.请分享更好的解决方案.提前致谢.

java bit-manipulation

5
推荐指数
1
解决办法
1532
查看次数

如何在x86中仅使用2个连续的leal指令将寄存器乘以37?

假设%edi包含x并且我想仅使用2个连续的leal指令结束37*x,我将如何进行此操作?

例如,你可以做到45倍

leal (%edi, %edi, 8), %edi   
leal (%edi, %edi, 4), %eax (to be returned)
Run Code Online (Sandbox Code Playgroud)

我不能为我的生活找出代替8和4的数字,以便结果(%eax)将是37x

x86 assembly x86-64 multiplication strength-reduction

5
推荐指数
1
解决办法
1302
查看次数

在不是地址/指针的值上使用LEA?

我试图了解地址计算指令的工作原理,尤其是leaq命令.然后当我看到leaq用于进行算术运算的例子时,我感到困惑.例如,以下C代码,

long m12(long x) {
return x*12;
}
Run Code Online (Sandbox Code Playgroud)

在组装中

leaq (%rdi, %rdi, 2), %rax
salq $2, $rax
Run Code Online (Sandbox Code Playgroud)

如果我的理解是正确的,那么leaq应该移动任何(%rdi, %rdi, 2)应该2*%rdi+%rdi评估的地址%rax.我感到困惑的是,因为值x存储%rdi在内,这只是内存地址,为什么%rdi乘以3然后左移这个内存地址 2等于x乘以12?是不是当我们%rdi用3时,我们跳到另一个没有值x的内存地址?

c x86 assembly memory-address

4
推荐指数
2
解决办法
4927
查看次数

80286:乘以 10 最快的方法是什么?

要将一个数字乘以 2 的任意倍数,我将对其进行多次移位。

有没有这样的技术可以在更少的周期内将数字乘以 10?

assembly micro-optimization x86-16

2
推荐指数
1
解决办法
1022
查看次数

逻辑/算术移位更少的位更快吗?

x>>2不是更快x>>31?换句话说,sar x, 2sar x, 31? 我做了一些简单的测试,它们似乎具有相同的速度。我将不胜感激任何确凿的证据。

c++ performance x86 assembly cpu-architecture

2
推荐指数
1
解决办法
111
查看次数

将位位置转换为掩码值

我想根据位位置动态计算掩码的值.

例如:32位值中第17位的掩码值为0x00020000,第18位的掩码值为0x00040000.因此,如果我知道像17,18等位位置,如何动态转换为掩盖C中的值?当然左移是一种方法(1<<171<<18).但我认为左移可能会消耗太多指令!或者左移是最好和最有效的方法?

c embedded

1
推荐指数
1
解决办法
178
查看次数