【问题标题】:Why are arithmetic operations slower in Docker?为什么 Docker 中的算术运算速度较慢?
【发布时间】:2020-09-05 13:49:39
【问题描述】:

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

附言我运行了多次程序来消除异常值。我不需要优化它,只是详细解释那里发生的事情。

test.cpp

#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);
}

Dockerfile

FROM ubuntu

WORKDIR /arythmetics

COPY a.out .

编译g++ -O0 test.cpp

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

docker run -it &lt;container&gt; .bin/bash

.\a.out

更新: 使用-static 标志编译后,两种环境下的程序运行时间相同 还有一个问题,为什么实际上是一样的?是不是应该有一些容器化开销?

【问题讨论】:

  • 您正在从 libc 调用 rand 函数,这可能在您的 Docker 容器中以不同方式实现。为了获得可靠的结果,请在主机和容器中使用完全相同的操作系统和软件包版本,或者使用类似 g++ -O0 -static-libstdc++ -static-libgcc test.cpp 的东西静态链接 libc。
  • 你能在 docker built FROM scratch 中运行相同的编译二进制文件吗?尽管您需要为此生成静态编译的二进制文件。
  • @AlexYu 仅使用 -static 进行测试,现在 docker 中的运行时间与主机中的运行时间相同,谢谢
  • 我认为stackoverflow.com/questions/21889053/… 很好地回答了这个问题。
  • 我会推荐这个:katacoda.com/openshift/courses/subsystems/…。不要混淆它使用podman 而不是docker - 它是一样的。它解释了哪些容器是隔离的,哪些不是。第 4 页直接指出:“容器只是作为容器运行时的子进程启动的常规 Linux 进程,而不是由用户在 shell 中运行命令”

标签: linux performance docker containers ubuntu-16.04


【解决方案1】:

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

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

g++ -O0 -static-libstdc++ -static-libgcc test.cpp

【讨论】:

    猜你喜欢
    • 2019-11-13
    • 2020-06-04
    • 1970-01-01
    • 2019-06-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-21
    • 2018-03-11
    相关资源
    最近更新 更多