【问题标题】:Why should I pass make -j an argument? (rather than leave it blank)为什么我应该传递 make -j 一个参数? (而不是留空)
【发布时间】:2014-03-16 04:00:50
【问题描述】:

我看到很多关于在跑步时传递 X 的良好值的讨论

make -j X

通常,人们认为 X 应该是系统内核数量的函数。在我的项目中,我通过省略 X 并简单地运行找到了最佳性能

make -j

如果您不关心为其他进程保留资源而只是想要最快的构建,是否有任何理由修复 X?

【问题讨论】:

    标签: build compilation makefile


    【解决方案1】:

    对于您的项目,使用不带参数的-j 可能是最好的解决方案。如果可以并行运行的作业数量相对较少,那就没问题了。

    但是,资源不是无限的。单独使用-j 告诉 make 它应该运行所有可能构建的作业,而不考虑系统资源。它不看你有多少 CPU、你有多少内存、你的系统上的负载有多高或其他任何东西。

    因此,如果您有一个非递归的构建系统,并且/或者包含成百上千个可以并行构建的文件(不要相互依赖),make 将尝试一次运行它们.就像当您尝试在系统中同时执行太多事情时,它会减慢速度并最终花费比一次执行几项更长的时间,因此运行太多作业会使您的系统崩溃。

    -j 为例,尝试构建 Linux 内核,看看它是如何为您工作的 :-)。

    【讨论】:

      【解决方案2】:

      更新:将与指定的'-l N'标志一起使用,请参阅load-average标志

       { 'l', floating, &max_load_average, 1, 1, 0, &default_load_average,
            &default_load_average, "load-average" },
      

      看起来 make 试图不消耗太多资源,请参阅 https://github.com/mirror/make/blob/master/src/job.c

        /* If we are running at least one job already and the load average
           is too high, make this one wait.  */
        if (!c->remote
            && ((job_slots_used > 0 && load_too_high ())
      #ifdef WINDOWS32
                || (process_used_slots () >= MAXIMUM_WAIT_OBJECTS)
      #endif
                ))
          {
            /* Put this child on the chain of children waiting for the load average
               to go down.  */
            set_command_state (f, cs_running);
            c->next = waiting_jobs;
            waiting_jobs = c;
            return 0;
          }
      

      对 load_too_high() 的注释:

      /* Determine if the load average on the system is too high to start a new job.
         The real system load average is only recomputed once a second.  However, a
         very parallel make can easily start tens or even hundreds of jobs in a
         second, which brings the system to its knees for a while until that first
         batch of jobs clears out.
      
         To avoid this we use a weighted algorithm to try to account for jobs which
         have been started since the last second, and guess what the load average
         would be now if it were computed.
      
         This algorithm was provided by Thomas Riedl <thomas.riedl@siemens.com>,
         who writes:
      
      !      calculate something load-oid and add to the observed sys.load,
      !      so that latter can catch up:
      !      - every job started increases jobctr;
      !      - every dying job decreases a positive jobctr;
      !      - the jobctr value gets zeroed every change of seconds,
      !        after its value*weight_b is stored into the 'backlog' value last_sec
      !      - weight_a times the sum of jobctr and last_sec gets
      !        added to the observed sys.load.
      !
      !      The two weights have been tried out on 24 and 48 proc. Sun Solaris-9
      !      machines, using a several-thousand-jobs-mix of cpp, cc, cxx and smallish
      !      sub-shelled commands (rm, echo, sed...) for tests.
      !      lowering the 'direct influence' factor weight_a (e.g. to 0.1)
      !      resulted in significant excession of the load limit, raising it
      !      (e.g. to 0.5) took bad to small, fast-executing jobs and didn't
      !      reach the limit in most test cases.
      !
      !      lowering the 'history influence' weight_b (e.g. to 0.1) resulted in
      !      exceeding the limit for longer-running stuff (compile jobs in
      !      the .5 to 1.5 sec. range),raising it (e.g. to 0.5) overrepresented
      !      small jobs' effects.
      
       */
      
      #define LOAD_WEIGHT_A           0.25
      #define LOAD_WEIGHT_B           0.25
      

      此外,正如人们所见,Windows 上的作业计数被限制为 MAXIMUM_WAIT_OBJECTS,即 64。

      【讨论】:

      • 只有在您提供-l 标志来设置最大负载级别时,才会执行“负载太高”检查。事实上,当使用 -j 而不使用任何参数时,通常情况下您也想使用 -l,但这不是问题所要问的。
      猜你喜欢
      • 2021-08-07
      • 1970-01-01
      • 1970-01-01
      • 2019-09-26
      • 2021-03-26
      • 1970-01-01
      • 1970-01-01
      • 2021-01-30
      • 1970-01-01
      相关资源
      最近更新 更多