相关疑难解决方法(0)

浮点除法与浮点乘法

通过编码是否有任何(非微优化)性能增益

float f1 = 200f / 2
Run Code Online (Sandbox Code Playgroud)

在比较中

float f2 = 200f * 0.5
Run Code Online (Sandbox Code Playgroud)

几年前我的一位教授告诉我,浮点除法比浮点乘法慢,但没有详细说明原因.

这句话适用于现代PC架构吗?

UPDATE1

关于评论,请同时考虑这个案例:

float f1;
float f2 = 2
float f3 = 3;
for( i =0 ; i < 1e8; i++)
{
  f1 = (i * f2 + i / f3) * 0.5; //or divide by 2.0f, respectively
}
Run Code Online (Sandbox Code Playgroud)

更新2 从评论中引用:

[我想]知道什么是算法/架构要求导致>除法在硬件上比复制要复杂得多

c++ floating-point micro-optimization

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

每个汇编指令需要多少个CPU周期?

我听说有英特尔在线书籍描述了特定汇编指令所需的CPU周期,但我无法找到它(经过努力).有人能告诉我如何找到CPU周期吗?

下面是一个例子,在下面的代码中,mov/lock是1个CPU周期,xchg是3个CPU周期.

// This part is Platform dependent!
#ifdef WIN32
inline int CPP_SpinLock::TestAndSet(int* pTargetAddress, 
                                              int nValue)
{
    __asm
    {
        mov edx, dword ptr [pTargetAddress]
        mov eax, nValue
        lock xchg eax, dword ptr [edx]
    }
    // mov = 1 CPU cycle
    // lock = 1 CPU cycle
    // xchg = 3 CPU cycles
}

#endif // WIN32
Run Code Online (Sandbox Code Playgroud)

顺便说一句:这是我发布的代码的URL:http://www.codeproject.com/KB/threads/spinlocks.aspx

cpu assembly cycle

48
推荐指数
5
解决办法
5万
查看次数

为什么大数字递增运算符(++)性能不佳?

我注意到,当递增计数器时,当计数器的值很大时,它会明显变慢.我在Chrome,Firefox和IE11中尝试过它,所有这些都表现得很差.

请参阅此处的 jsperf test (下面的代码):

var count1 = 0;
var count2 = new Date().getTime();
var count3 = 1e5;
var count4 = 1e9;
var count5 = 1e12;
var count6 = 1e15;

function getNum1() {
  return ++count1;
}

function getNum2() {
  return ++count2;
}

function getNum3() {
  return ++count3;
}

function getNum4() {
  return ++count4;
}

function getNum5() {
  return ++count5;
}

function getNum6() {
  return ++count6;
}
Run Code Online (Sandbox Code Playgroud)

为什么会这样?

javascript

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

Java中的int vs float算术效率

我正在编写一个使用Dijkstra算法的应用程序来查找图中的最小路径.图中节点和边的权重是float数字,因此算法在浮点数上做了很多算术.如果我将所有重量转换为ints,我可以获得运行时间的改善吗?在Java中,int算术运算是否比浮动运算更快?

我试着写一个简单的基准来检查出来,但我对我得到的结果不满意.可能编译器已优化程序的某些部分,因此结果对我来说不太好.


编辑:

我试图解决的问题是在信息检索字段中.应用程序应显示作为一组关键字提出的查询的答案.

我的数据结构是加权有向图.给定一组叶节点,我必须找到连接这些节点并向用户显示答案的最小树.权重由部分基于tf/idf技术的加权函数指定.用户不知道我分配给节点和边缘的权重,他只想看到与他提出的查询相关的答案.因此不需要精确的结果,只需根据他们的权重枚举答案.只是本地使用加权函数(正如我提到它基于tf/idf)给出了浮点权重,所以我到目前为止使用了浮点数.

我希望这会为这个问题增加一些背景知识.

java math performance primitive

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

在预测现代超标量处理器上的操作延迟时需要考虑哪些因素以及如何手动计算它们?

我希望能够手动预测任意算术的长度(即没有分支或内存,尽管这也很好)x86-64汇编代码将采用特定的体系结构,考虑到指令重新排序,超标量,延迟,消费者价格指数等

什么/描述必须遵循的规则才能实现这一目标?


我想我已经找到了一些初步规则,但是我没有找到任何关于将任何示例代码分解为这个详细程度的引用,所以我不得不做一些猜测.(例如,英特尔优化手册甚至几乎没有提到指令重新排序.)

至少,我正在寻找(1)确认每条规则是正确的,或者是每条规则的正确陈述,以及(2)我可能忘记的任何规则的列表.

  • 每个循环发出尽可能多的指令,从当前循环开始按顺序开始,并且可能与重新排序缓冲区大小一样远.
  • 如果出现以下情况,可以在给定周期发出指令:
    • 没有影响其操作数的指令仍在执行中.和:
    • 如果它是浮点指令,则它之前的每个浮点指令都被发出(浮点指令具有静态指令重新排序).和:
    • 该循环有一个功能单元可用于该指令.每个(?)功能单元是流水线的,这意味着它可以在每个周期接受1个新指令,并且对于给定功能类的CPI,总功能单元的数量是1/CPI(这里模糊不清:可能是例如addps并且subps使用相同的功能) unit?我如何确定?).和:
    • 4此循环已经发出少于超标量宽度(通常)指令的数量.
  • 如果不能发出指令,则处理器不会发出任何称为"停顿"的条件.

例如,请考虑以下示例代码(计算交叉产品):

shufps   xmm3, xmm2, 210
shufps   xmm0, xmm1, 201
shufps   xmm2, xmm2, 201
mulps    xmm0, xmm3
shufps   xmm1, xmm1, 210
mulps    xmm1, xmm2
subps    xmm0, xmm1
Run Code Online (Sandbox Code Playgroud)

我试图预测Haswell的延迟看起来像这样:

; `mulps`  Haswell latency=5, CPI=0.5
; `shufps` Haswell latency=1, CPI=1
; `subps`  Haswell latency=3, CPI=1

shufps   xmm3, xmm2, 210   ; cycle  1
shufps   xmm0, xmm1, 201   ; cycle  2
shufps   xmm2, xmm2, 201   ; …
Run Code Online (Sandbox Code Playgroud)

assembly pipeline latency x86-64 superscalar

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

将sqrt(n)与理性p/q进行比较

给出一个整数n和一个有理p/q(pq是整数).

你如何比较sqrt(n)p/q

解决方案1:sqrt(n) <= (double) p / q
应该工作,但是调用sqrt比使用乘法/除法慢.

解决方案2: (double) n * q * q <= p * p
更好,但我不禁想到因为我们使用浮点数,如果p/q非常接近sqrt(n),我们可能会得到错误的答案.此外,它需要将整数转换为浮点数,这比使用整数(稍微)慢一些.

解决方案3:n*q*q <= p*p
更好,但是如果pq由于溢出而变大(例如,当使用64位整数时,如果pq > = 2 ^ 32),则会遇到麻烦.

解决方案4:使用具有bignum库的解决方案3 /使用具有未绑定整数的编程语言.

解决方案5: (q / p) * n <= p / q
成功避免任何溢出问题,但我不确定这在所有情况下都是正确的,因为整数除法...

所以...我很乐意选择解决方案2或4,但我想知道是否有人有巧妙的技巧来解决这个问题,或者可能是解决方案5工作(或不工作)的证明(或反例).

math floating-point performance

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

64位双向量的向量比32位无符号整数的向量更快?

我有两种代码迭代大小为500的矢量设计.其中一个设计包含64位双精度数组,第二个设计使用包含32位整数的数组.我期待32位设计更快,因为更多有用的数据可以打包在缓存中.

编译器MSVC,CPU Ivy Bridge,编译64位模式.

这是代码1,使用32位整数(在2600个 CPU周期中运行):

#include <vector>
#include <iostream>

int main(){

    std::vector<unsigned int> x1;
    std::vector<unsigned int> x2;
    std::vector<unsigned int> x3;
    x1.resize(500);
    x2.resize(500);
    x3.resize(500);

    for(int i =0; i<500; i++){
        x1[i] = i;
        x2[i] = 2*i;
        x3[i] = 4*i;
    }


    int counter = 0;
    while(counter < 1000){
        unsigned long long start = 0;
        unsigned long long end = 0;

        double m = 0;
        double n = 0;

        start = __rdtsc();

        for(int i=0; i < 500; i++){
            unsigned int a = …
Run Code Online (Sandbox Code Playgroud)

c++ cpu optimization performance compiler-optimization

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

浮点 Div/Mul &gt; 比 Add/Sub 慢 30 倍?

我最近读了这篇文章:现代硬件上的浮点与整数计算,并且对我自己的处理器在这个准基准上的性能感到好奇,所以我将代码的两个版本放在一起,一个在 C# 中,一个在 C++ 中(Visual Studio 2010 Express)并对它们进行了优化编译,看看会出现什么结果。我的 C# 版本的输出相当合理:

int add/sub: 350ms
int div/mul: 3469ms
float add/sub: 1007ms
float div/mul: 67493ms
double add/sub: 1914ms
double div/mul: 2766ms
Run Code Online (Sandbox Code Playgroud)

当我编译并运行 C++ 版本时,出现了一些完全不同的东西:

int add/sub: 210.653ms
int div/mul: 2946.58ms
float add/sub: 3022.58ms
float div/mul: 172931ms
double add/sub: 1007.63ms
double div/mul: 74171.9ms
Run Code Online (Sandbox Code Playgroud)

我预计会有一些性能差异,但不会这么大!我不明白为什么 C++ 中的除法/乘法比加法/减法慢得多,而托管 C# 版本更符合我的期望。该函数的C++版本代码如下:

template< typename T> void GenericTest(const char *typestring)
{
    T v = 0;
    T v0 = (T)((rand() % 256) / 16) + 1;
    T v1 …
Run Code Online (Sandbox Code Playgroud)

c# c++ floating-point performance x86

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

使用double和int的算法速度?

double竞争算法与int价值观相比如何?有很大差异,还是可以忽略?

就我而言,我有一个Integers到目前为止使用的画布.但是现在我正在实施扩展,我可能会将所有内容都切换到Double.这会对计算产生重大影响吗?如果是这样,可能会将双打四舍五入到只有几个分数来优化性能?

或者我完全走在过度优化的道路上,应该只使用双打没有任何头痛?

java double gwt integer canvas

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

一个线程比另一个线程慢,即使它们做同样的事情

我只是通过尝试创建一些小程序来学习多线程,我发现了一个特定的东西,我不知道为什么它是这样的.

我有两个课程,他们都数到20亿,最后他们打印出时间来完成它.它们位于不同的文件中.第一个可以在大约2秒内完成(它会更快,但我也在那里做其他的东西),和新的线程(新的Runnable())

在主要课程中要慢得多,花了大约8秒才能完成.你可以解释一下原因吗?这是代码.谢谢.

public class First implements Runnable {

private long startTime, endTime;
public static double count = 0;

@Override
public void run() {
    startTime = System.currentTimeMillis();

    for (int count = 0; count <= 2000000000L; count++);

    endTime = System.currentTimeMillis();
    System.out.println(endTime - startTime); //it is done in about 2seconds
  }
 }


public class Threads {

   public static void main(String[] args){

         First f = new First();
         f.run();

     new Thread(new Runnable() {

        @Override
        public void run() {

            long startTime, endTime;
            double count; …
Run Code Online (Sandbox Code Playgroud)

java multithreading

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

为什么浮点运算被认为是昂贵的?

我读到gprof(函数分析)和其他分析方法可以返回执行程序时发生的浮点运算的数量,因此想知道Flops如何比常规运算贵得多?

profiling flops

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

用双精度数替换所有整数有哪些缺点?

即使在索引到数组时,一致使用浮点类型来表示整数有哪些潜在的缺点?假设一个面向性能的 C 库的上下文。可以在 64 位整数和 64 位浮点数之间进行选择。

我对做这样的事情感到不舒服,因为doubles 不是用于索引的,并且使用工具来完成其设计目的之外的事情通常会带来风险。但我想了解是否有合理的理由避免这样做。

为了解决显而易见的问题:

  • 当然,某些强制转换可能需要double[ ]运算符一起使用。
  • 当然,IEEE 754double无法表示与 64 位整数类型一样多的不同整数,但在可预见的将来,53 位可能足以用于索引数组。

事实上,浮点类型的这种用法在野外随处可见。例如,R 没有 64 位整数,并且通过使用doubles 进行索引来支持大型数组。在编写必须与 R 互操作的代码时,必须考虑是否也这样做。

c floating-point performance

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