计算机如何对2个数字进行乘法运算,比如100*55.
我的猜测是计算机重复添加以实现乘法.当然,这可能是整数的情况.但是对于浮点数,必须有一些其他逻辑.
注意:这在面试中被问到了.
我在 Java 和 Rust 上运行了一个相同的小型基准测试。
爪哇:
public class Main {
private static final int NUM_ITERS = 100;
public static void main(String[] args) {
long tInit = System.nanoTime();
int c = 0;
for (int i = 0; i < NUM_ITERS; ++i) {
for (int j = 0; j < NUM_ITERS; ++j) {
for (int k = 0; k < NUM_ITERS; ++k) {
if (i*i + j*j == k*k) {
++c;
System.out.println(i + " " + j + " " + k); …Run Code Online (Sandbox Code Playgroud) 有时gcc使用32位寄存器,当我希望它使用64位寄存器时.例如以下C代码:
unsigned long long
div(unsigned long long a, unsigned long long b){
return a/b;
}
Run Code Online (Sandbox Code Playgroud)
使用-O2选项编译(省略一些样板文件):
div:
movq %rdi, %rax
xorl %edx, %edx
divq %rsi
ret
Run Code Online (Sandbox Code Playgroud)
对于无符号除法,寄存器%rdx需要0.这可以通过xorq %rdx, %rdx但xorl %edx, %edx似乎具有相同的效果来实现.
至少在我的机器上没有性能提升(即加速)进行xorl了xorq.
我实际上不只是一个问题:
xorl并且不使用xorw?xorl比这更快的机器xorq?我正在看一些关于算法的讲座,教授用乘法作为如何改进朴素算法的例子......
它让我意识到乘法并不是那么明显,虽然在我编码时我只是认为它是一个简单的原子操作,乘法需要一个算法来运行,它不像对数字求和那样工作。
所以我想知道,现代桌面处理器实际使用什么算法?我猜他们不依赖对数表,也不用数以千计的总和进行循环......
正如我一直所理解的那样,AMD 通过对英特尔的指令集进行逆向工程来构建他们的 CPU,现在支付给英特尔使用他们的指令集,而英特尔对 AMD 的 64 位指令也是如此。
这就是 Windows 可以安装在两种类型的 CPU 上的方式,而无需购买特定版本,例如为 ARM 编译的版本,因此所有应用程序、游戏等都以相同的方式工作,可在 CPU 上互换工作......
然而最近有些事情让我质疑其中的一些......
首先,我注意到一些游戏在我的系统 (AMD) 上有点滞后,阅读后发现游戏针对 Intel CPU 进行了优化......
此外,OSX 是在 Intel CPU 上销售的,但在发现 hackintosh 社区之后,事实证明让 OSX 在 AMD 上运行是可能的,但非常困难。这是因为 OSX 再次是为英特尔设计的......
这些事情之后..
针对 Intel 或 AMD 进行优化意味着什么?如果它们旨在相互替换,怎么可能对一个而不是另一个进行不同/优化?即都支持相同的指令等。
我在x86-64汇编中开发了一个程序,该程序需要通过相同的操作进行多次迭代:
IMUL rdx, 3 # rdx is always different
Run Code Online (Sandbox Code Playgroud)
但是,我需要使运行时更快,因此我从上面想到了对该特定行的优化:
MOV rcx, rdx
SHL rdx, 1
ADD rdx, rcx
Run Code Online (Sandbox Code Playgroud)
现在我问你们:这种修改会改善程序的运行时间(减少时钟),还是我应该坚持使用该IMUL命令?