【问题标题】:fork seems to copy when unnecessaryfork 似乎在不必要时复制
【发布时间】:2021-12-27 13:12:21
【问题描述】:

我正在尝试 fork 的 CoW(查看编辑了解更详细的背景,可能完全不相关

#include <stdio.h>
#include <time.h>
#include <unistd.h>

#define N 262144
struct {
    int n;
    int padding[1023];
} arr[N];
int main() {
    int i, sp = 0, t, tx = clock();
    for (i=0; i<N; ++i) arr[i].n = i;
    printf ("Init Time: %d\n", clock()-tx);
    #if 1
        sp = fork();
        if(!sp) _exit(0);
        waitpid(sp, &sp, 0);
    #endif
    // 5045 without fork
    // 104192 with fork
    t = clock();
    for (i=0; i<N; ++i) arr[i].n = -i;
    printf ("Runner %d Time: %d\n", sp, clock() - t);
    getchar();
    return 0;
}

fork 使以后的内存访问变慢。

fork 复制会使其变慢吗?如果是这样,为什么?我在 Ubuntu 20.04.3 LTS 上运行

【问题讨论】:

  • 你忘了打电话给waitpid(2),你总是应该测试,并保留fork(2)的结果,这可能会失败!另请阅读 fork 上的维基页面 - 请注意 copy-on-write 技术和技巧。
  • @BasileStarynkevitch waitpid 没有帮助。编辑问题
  • 非常好的问题。我喜欢这些基准测试。

标签: linux fork


【解决方案1】:

尝试在/usr/bin/time -v 下运行它并观察 Minor (reclaiming a frame) page faults: 行。

即使孩子立即退出,叉子也会使其翻倍。

增加的时间似乎完全是由于这些页面错误。

据推测,在分叉时,内核会在写入时将页面设置为错误,以期需要复制。 如果在这样的页面错误时孩子已经死了,则复制的需要被取消(该页面不再与任何人共享,因此无需费心复制它),但您仍然需要为页面错误的命中付费。

现在,如果您让孩子保持活动状态,那么 pagefault 处理程序也应该需要进行复制,实际上,保持孩子活动会增加循环持续时间数倍。那应该是完整的写时复制。

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <time.h>
#include <unistd.h>

#define N 262144
struct {
    int n;
    int padding[1023];
} arr[N];
int main() {
    int i, t, tx = clock();
    pid_t sp=0;
    for (i=0; i<N; ++i) arr[i].n = i;
    printf ("Init Time: %ld\n", clock()-tx);

    #if 1
    if(0>(sp = fork())) return 1;
    enum  { KEEP_THE_KID_EH = 1 };
    if(!sp){ if(KEEP_THE_KID_EH){ for(;;) pause(); }  exit(0); }
    #endif

    t = clock();
    for (i=0; i<N; ++i) arr[i].n = -i;
    printf ("Runner %ld Time: %ld\n", (long)sp, clock() - t);
    /*getchar();*/
    if(sp) kill(sp,SIGTERM);
    return 0;
}

我的时间是:

7371 without fork
189073 with fork
1092145 with fork and the kid kept

【讨论】:

  • 很好的解释。是要问旧代码,但那只是因为我在睡觉前启动了计时器......
猜你喜欢
  • 2012-12-05
  • 1970-01-01
  • 2020-05-30
  • 2016-02-06
  • 2011-08-29
  • 2013-06-11
  • 2017-09-22
  • 1970-01-01
  • 2017-12-06
相关资源
最近更新 更多