Issue
I'm trying the CoW of fork
(see edit for more detailed background, which may be quite unrelated)
#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;
}
The fork
makes later memory accesses slower.
Do fork
copy making it slow? If so, why? I run on Ubuntu 20.04.3 LTS
Solution
Try running it under /usr/bin/time -v
and watch the Minor (reclaiming a frame) page faults:
line.
The fork makes it double even if the child exits immediately.
The increased time seems to be solely due to these page faults.
Presumably, upon a fork, the kernel sets the pages to fault on a write in expectation of a need to copy. If the child is dead by the time such a page faults, the need to copy is canceled (the page is no longer shared with anyone so no need to bother copying it), but you still pay for the page faults hitting.
Now if you keep the child alive, then the pagefault handler should also need to do the copy, and indeed, keeping the child alive increases the loop duration several extra times. That should be the full copy-on-write.
#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;
}
My times are:
7371 without fork
189073 with fork
1092145 with fork and the kid kept
Answered By - PSkocik