当前位置: 首页 > 知识库问答 >
问题:

为什么Docker中的算术运算较慢?

须巴英
2023-03-14

我有一个简单的程序来测量浮点乘法(和随机生成,编译g-O0)。在主机(Ubuntu 16.04)上运行时,每10000000次乘法得到约1.6秒,在图像“Ubuntu”的容器中运行时(无需重新编译),得到约3.6秒。有人能解释为什么它慢了2.5倍吗?

p、 我多次运行程序来消除异常值。我不需要优化它,只需要详细解释那里发生了什么。

#include <cstdio>
#include <math.h>
#include <chrono>

using namespace std;
using namespace std::chrono;

// timer cribbed from
// https://gist.github.com/gongzhitaao/7062087
class Timer
{
    public:
    Timer() : beg_(clock_::now()) {}
    void reset() { beg_ = clock_::now(); }
    double elapsed() const
    {
        return duration_cast<second_>(clock_::now() - beg_).count();
    }

    private:
    typedef high_resolution_clock clock_;
    typedef duration<double, ratio<1>> second_;
    time_point<clock_> beg_;
};

#define randf() ((double)rand()) / ((double)(RAND_MAX))

double warmup(Timer tmr) {
    tmr.reset();
    for (int i = 0; i < 100000000; i++)
    {
        double r1 = randf();
        double r2 = randf();
    }
    double elapsed = tmr.elapsed();
    return elapsed;
}

double test(Timer tmr) {
    double total = 0.0;
    tmr.reset();
    for (int i = 0; i < 100000000; i++)
    {
        double r1 = randf();
        double r2 = randf();
        total += r1*r2;
    }
    double elapsed = tmr.elapsed();
    return elapsed;
}

double avg(double* arr) {
    double res = 0.0;
    for (int i = 0; i < 10; i++) {
        res += *(arr + i);
    }
    return res / 10;
}


int main()
{
    double total;
    int total2;
    Timer tmr;
    

    double warmup_runs[10];
    for (int i = 0; i < 10; i++)
    {
        warmup_runs[i] = warmup(tmr);
        printf("warm - %f\n", warmup_runs[i]);
    }
    double avg_warmup = avg(warmup_runs);
    printf("avg warm - %f\n", avg_warmup);

    const int runs = 10;
    double result[runs];
    for (int i = 0; i < runs; i++)
    {
        result[i] = test(tmr);
        printf("real - %f\n", result[i]);
    }
    double avg_result = avg(result);
    printf("avg real - %f\n", avg_result);

    printf("d - %f\n", avg_result - avg_warmup);
}
FROM ubuntu

WORKDIR /arythmetics

COPY a.out .

编译g-O0测试。cpp

要在构建后使用的容器内运行:

docker运行它

.\a.out

UPDATE:使用-静态标志编译后,程序运行时间在两个环境中是相同的还有一个问题,为什么它实际上是相同的?是不是应该有一些集装箱化的开销?


共有1个答案

仉梓
2023-03-14

您正在从libc调用rand函数,这可能在Docker容器中以不同的方式实现。

要获得可靠的结果,请在主机和容器中使用完全相同的操作系统和软件包版本,或者使用以下方式静态链接libc:

g++ -O0 -static-libstdc++++ -static-libgcc test.cpp
 类似资料:
  • 当我尝试测量算术运算的执行时间时,我遇到了非常奇怪的行为。包含< code>for循环且循环体中有一个算术运算的代码块的执行速度总是慢于在< code>for循环体中有两个算术运算的相同代码块。下面是我最后测试的代码: 我测试了不同级别的代码优化(,,和),使用不同的在线编译器(例如onlinegdb.com),在我的工作机器上,在我的hame PC和笔记本电脑上,在RaspberryPi和同事的

  • 考虑以下代码: 这会产生编译错误,因为添加2字节的结果是Int。 为了解决这个问题,我需要手动将结果转换回字节: 这是非常反直觉的。为什么算术运算符是这样工作的?

  • 问题内容: 因此我正在研究的类源代码()以了解如何将转换为。似乎正在使用称为(第433行)的程序包私有方法将转换为数组。 尽管代码并不难理解,但是有多行代码使用逐位移位运算而不是简单的算术乘法/除法,例如以下几行代码: 和 我只是不明白这样做的目的,这实际上是一种优化,并且会影响算法的运行时间吗? 编辑: 换句话说,由于编译器在内部进行这种类型的优化,因此这种手动优化是否必要? 问题答案: 我不知

  • 主要内容:numpy.reciprocal(),numpy.power(),numpy.mod(),复数数组处理函数NumPy 数组的“加减乘除”算术运算,分别对应 add()、subtract()、multiple() 以及 divide() 函数。 注意:做算术运算时,输入数组必须具有相同的形状,或者符合数组的广播规则,才可以执行运算。 下面看一组示例: 输出结果: 下面介绍了 NumPy  中其他重要的算术运算函数。 numpy.reciprocal() 该函数对数组中的每个元素取倒数,并

  • 大多数都要进行算术运算。算术运算符见图 1.10,注意这里使用了许多代数中没有使用的符号。星号(*)表示乘法、百分号(%)表示求模(modulus)将在稍后介绍。图1.10所示的算术运算符都是二元运算符,即这些运算符取两个操作数。例如表达式 "integer1+integer2" 包含二元运算符 “+” 和两个操作数 integer1 和 integer2。 C++操作 算术运算符 代数表达式 C

  • 运算符是处理数据的基本方法,用来从现有的值得到新的值。JavaScript 提供了多种运算符,覆盖了所有主要的运算。 概述 JavaScript 共提供10个算术运算符,用来完成基本的算术运算。 加法运算符:x + y 减法运算符: x - y 乘法运算符: x * y 除法运算符:x / y 指数运算符:x ** y 余数运算符:x % y 自增运算符:++x 或者 x++ 自减运算符:--x