关于乘法指令与加法指令哪个快的有关问题解答

关于乘法指令与加法指令哪个快的问题解答
http://sj256.com/content/?62.html

------解决方案--------------------
探讨

关闭优化是为了让你的测试代码真正生效
例如代码
for(i=0;i<10000;i++)
{
a=b+c;
}
这样的代码优化后不是执行10000次,而是仅执行1次,测得的时间是0。编译器优化掉了重复的计算。

------解决方案--------------------
还是看对应的汇编代码吧。
------解决方案--------------------
帮顶。。。。从题目来看没有可比性
------解决方案--------------------
查一下cpu的指令手册就有了。
add
Clocks Size
Operands 808x 286 386 486 Bytes
reg,reg 3 2 2 1 2

mem,reg 16+EA 7 7 3 2-4 (W88=24+EA)
reg,mem 9+EA 7 6 2 2-4 (W88=13+EA)
reg,immed 4 3 2 1 3-4
mem,immed 17+EA 7 7 3 3-6 (W88=23+EA)

accum,immed 4 3 2 1 2-3

mul
Clocks Size
Operands 808x 286 386 486 Bytes
reg8 70-77 13 9-14 13-18 2

reg16 118-113 21 9-22 13-26 2
reg32 - - 9-38 13-42 2-4
mem8 (76-83)+EA 16 12-17 13-18 2-4
mem16 (124-139)+EA 24 12-25 13-26 2-4

mem32 - - 12-21 13-42 2-4



------解决方案--------------------
探讨

引用:
不需要的,你想防止循环被优化掉,只要再循环后调用一次循环中的计算变量(如用printf输出一下),或者对相应变量volatil……

这里主要是测量加法指令和乘法指令的时间,而不是优化还是不优化程序,如果加了printf或是其他的东西,那么测试得到的大部分时间就不是真正的加法指令的时间了。

这里的代码主要是为了纠正那些通过代码得出了“乘……

------解决方案--------------------
探讨
用纯汇编写不涉及到cache命中率,因为操作数只是寄存器,而不涉及内存
例如add eax,edx
只是完成无意义的加法运算而已,至于当时eax,edx内容实际是多少并不关心。
计算纯的加法指令时间,而不是计算内存中的数值,实际上如果计算内存中的数值,不管在不在cache中,都要加一条类似mov eax,a的汇编指令,即还是把操作数移到寄存器中才能计算,而这样得到的结果就又不是纯粹的加法指令的时间了,而是多出来一半的存储转移时间,至于存储转移发生在寄存器和cache间还是发生在和物理内存间或是硬盘上的虚拟内存间那都会有不同的时间。

------解决方案--------------------
‘任何一个非0数乘0’的速度都应该比‘两个非0数相加’快吧。(^_^)
------解决方案--------------------
上代码(gcc x86-64, -O3 优化):
C/C++ code
#include <cstdio>
#include <stdint.h>

using namespace std;

uint64_t rdtsc()
{
    uint32_t eax, edx;
    asm volatile ("rdtsc" : "=a"(eax), "=d"(edx));
    return ((uint64_t)edx << 32) | eax;
}

int main()
{
    uint64_t start, end;
    start = rdtsc();
    for(int i = 0; i < 100000000; ++i)
    {
        asm volatile ("imul %0, %%eax" : : "r"(0) : "eax");
        asm volatile ("imul %0, %%ebx" : : "r"(0) : "ebx");
        asm volatile ("imul %0, %%ecx" : : "r"(0) : "ecx");
        asm volatile ("imul %0, %%edx" : : "r"(0) : "edx");
        asm volatile ("imul %0, %%eax" : : "r"(0) : "eax");
        asm volatile ("imul %0, %%ebx" : : "r"(0) : "ebx");
        asm volatile ("imul %0, %%ecx" : : "r"(0) : "ecx");
        asm volatile ("imul %0, %%edx" : : "r"(0) : "edx");
        asm volatile ("imul %0, %%eax" : : "r"(0) : "eax");
        asm volatile ("imul %0, %%ebx" : : "r"(0) : "ebx");
        asm volatile ("imul %0, %%ecx" : : "r"(0) : "ecx");
        asm volatile ("imul %0, %%edx" : : "r"(0) : "edx");
    }
    end = rdtsc();
    
    printf("ticks: %lu\n", (unsigned long)(end - start));
    
    start = rdtsc();
    for(int i = 0; i < 100000000; ++i)
    {
        asm volatile ("imul %0, %%eax" : : "r"(0x55555555) : "eax");
        asm volatile ("imul %0, %%ebx" : : "r"(0x55555555) : "ebx");
        asm volatile ("imul %0, %%ecx" : : "r"(0x55555555) : "ecx");
        asm volatile ("imul %0, %%edx" : : "r"(0x55555555) : "edx");
        asm volatile ("imul %0, %%eax" : : "r"(0x55555555) : "eax");
        asm volatile ("imul %0, %%ebx" : : "r"(0x55555555) : "ebx");
        asm volatile ("imul %0, %%ecx" : : "r"(0x55555555) : "ecx");
        asm volatile ("imul %0, %%edx" : : "r"(0x55555555) : "edx");
        asm volatile ("imul %0, %%eax" : : "r"(0x55555555) : "eax");
        asm volatile ("imul %0, %%ebx" : : "r"(0x55555555) : "ebx");
        asm volatile ("imul %0, %%ecx" : : "r"(0x55555555) : "ecx");
        asm volatile ("imul %0, %%edx" : : "r"(0x55555555) : "edx");
    }
    end = rdtsc();
    printf("ticks: %lu\n", (unsigned long)(end - start));
    
    return 0;
}