- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在测试 hacker's delight book 中的 divs10 函数吞吐量,在我的 jdk 1.7 64 位版本 21 和 i7 intel box 上用 java 编码处理器:7vendor_id :正版英特尔CPU系列:6型号:26型号名称:Intel(R) Core(TM) i7 CPU 920 @ 2.67GHz
我想知道为什么默认的 java 运算符/比 hacker's delight book 中的 divs10 函数快,结果显示 divs10 比“/”运算符慢 3 倍,令我惊讶。
任何人都可以告诉我是否有任何奇特的内部 jvm 可以使用?
源代码如下。
public class div10 {
public static final int divs10(int n) {
int q, r;
n = n + (n >> 31 & 9);
q = (n >> 1) + (n >> 2);
q += q >> 4;
q += q >> 8;
q += q >> 16;
q = q >> 3;
r = n - ((q << 3) + (q << 1));
return q + ((r + 6) >> 4);
}
public static void main(String[] args) {
/*
long count = 0;
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
if ( (i/10) != divs10(i) ) {
System.err.println("error dividing :" + i );
}
if ((i & 0xFFFFFFF ) == 0 ) {
System.out.println("Finished:" + Long.toHexString(count) + ":" + count + ":" + i);
}
count++;
}
System.out.println("Success:" + count);
*/
long start = System.nanoTime();
long count = 0L;
int iter = 100_000;
for (int j = 0; j < 10; j++)
for (int i = -iter; i < iter; i++) {
count += (i/10);
}
for (int j = 0; j < 10; j++)
for (int i = -iter; i < iter; i++) {
count += divs10(i);
}
System.out.println(count + " warm up done ") ;
start = System.nanoTime();
count = 0L;
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
count += i/10;
}
System.out.println(count + ", took:" + (System.nanoTime() - start) / 1000_000L + " ms, " + (System.nanoTime() - start) / ((long)Integer.MAX_VALUE - (long)Integer.MIN_VALUE) + " ns per ops" ) ;
start = System.nanoTime();
count = 0L;
for (int i = Integer.MIN_VALUE; i < Integer.MAX_VALUE; i++) {
count += divs10(i);
}
System.out.println(count + ", took:" + (System.nanoTime() - start) / 1000_000L + " ms, " + (System.nanoTime() - start) / ((long)Integer.MAX_VALUE - (long)Integer.MIN_VALUE) + " ns per ops" ) ;
}
}
最佳答案
更新:查看较新的Ivy Bridge table时(第 174 页),我看到所有的延迟都是 1。这意味着我之前的解释是不正确的。
尝试计算在 divs10
方法中执行的指令是 27(没有函数调用的开销)指令。您正在执行的操作要求在下一个操作开始之前完成前一个操作。所以这意味着你应该考虑指令的延迟。根据 Ivy Bridge 指令表,所有涉及的指令都有 1 个时钟周期的延迟。这为您提供了总共 27 个时钟周期。
这是与单个 IDIV(8 位)指令的比较。在表中,我可以发现这需要大约 20 个时钟周期的延迟。
粗略估计:27 个周期/20 个周期 = 慢 1.35 倍。这与您的结果不一致。我不是这方面的专家,但我认为这是因为使用 IDIV 指令的除法可以并行运行,因为它们是独立的。 IDIV 指令的吞吐量为 8 个时钟周期。这允许 CPU 以每 52 个周期可以运行大约 4 个除法的方式优化指令(这是一个估计值)。
因此,要使用位移算法执行 4 个除法,您需要 108 个周期,而 IDIV 需要大约 64 个时钟周期。这给出:108/52 = 慢 2.1 倍。
这接近于您测量的比率。我想剩余的额外时间用于函数调用的开销。也许 CPU 的优化比我估计的要好。
关于java - 为什么整数的java除法比黑客的喜悦实现更快,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22312030/
我正在尝试编写一个简单的除法函数,但出现错误 PS C:\Users\john> Function Div($x, $y) { $x / $y } PS C:\Users\john> Div (1,
试图找出这个伪代码。以下假设...... 我只能使用无符号和有符号整数(或长整数)。 除法返回一个没有余数的实数。 MOD 返回一个实数。 不处理分数和小数。 INT I = 41828; INT C
如果我有以下表格并且我在关系代数中执行 R1/R2,结果会是一个具有 A 值 1 和 3 的表格吗?我有点困惑,因为我知道 3 将是一个结果,因为它包含 5 和 1,但结果 1 除了匹配的值之外还有
//Declare and intialize variables - programmer to provide initial values Scanner in = new Scanne
除法运算符在 scala BigDecimal 上有什么用? val d1 = BigDecimal(2) val d2 = BigDecimal(3) val div = d1 / d2 //thr
这个问题在这里已经有了答案: How can I divide properly using BigDecimal (2 个答案) 关闭 6 年前。 我在这里做错了什么?很确定这是正确的,我能够打印
好的 - 已经为此苦苦挣扎了一段时间。我刚刚开始学习 Python,所以非常新。 我有一个元组列表,需要按每个元组中值的比率进行排序。 输入: L = [(1,3), (1,7), (4,8)] 返回
我有一个奇怪的问题,我收到计算机生成的方程式(作为字符串),其中偶尔会出现零或一和零的乘法/除法。这些等式将以字符串形式呈现给用户。 我知道我可以通过实现一种解析器来删除等式中的这些冗余部分,但我很好
我有两个变量:count,这是我过滤的对象的数量,以及每页的常量值。我想将计数除以 per_page 并获得整数值,但无论我尝试什么 - 我都得到 0 或 0.0: >>> count = frien
我尝试在 Go 中获得 2.4/0.8 == 3 w:=float64(2.4) fmt.Println(math.Floor(w/0.8),math.Floor(2.4/0.8) ) 它给了我“2
程序清单: # val_caculate.py a = 10 # a是整数 print('10/3 = ',10/3) print('9/3 = ',9/3) pri
我是 java 新手,所以我需要你对我正在进行的项目的帮助!我定义了一些计数器,这些是我将使用的: int[] acceptCounters = {}; int[] acceptFailCounter
我正在除 2 个 BigInteger 值 N = 9440056782685472448790983739834832785827768777249804302814308027414135716
我的应用程序中有使用 array.reduce 将数字相乘的代码。它看起来像这样: // Private function to multiply field values together func
我目前创建了一个名为 Array Math 的类,它将乘法加载到 10x10 数组中,如代码下显示的图像所示,但是我想要做的是在乘法后将每个位置除以 2。换句话说,(行 * 列)/2 目前我只是将这些
我正在使用代表货币金额的 BigDecimal 值。我需要将此金额分成 6 个费率,前 5 个费率四舍五入为 5,其余的为第 6 个费率。 BigDecimal numberOfRates = new
这个问题必须使用递归来解决。 我尝试使用 “else” 之后的代码来使用 int temp 计算商,该 temp 计算可以除以多少次 (temp = dividend - divisor)。 int
我知道这一定是有史以来最简单的事情,但我是这里的初学者。为什么我运行时会出现语法错误 document.write(10 / 2 + ""); //Divide 10 by 5 to get 2
这应该是一个非常基本的东西,但不知何故我没有看到问题。 #include template inline void i2c(const int & ind, int & i, int &j) {
我正在做课本中的一些家庭作业,并且有一些关于某些算术运算的浮点舍入/精度的问题。 如果我像这样从 int 中转换 double : int x = random(); double dx = (dou
我是一名优秀的程序员,十分优秀!