Performance 有没有办法找出或控制Elixir中哪个进程运行在哪个CPU核上?

Performance 有没有办法找出或控制Elixir中哪个进程运行在哪个CPU核上?,performance,parallel-processing,erlang,elixir,beam,Performance,Parallel Processing,Erlang,Elixir,Beam,我用Elixir制作了一个多进程插入排序程序。但是,在32核机器上运行时,它比单进程插入排序慢。 如果发送消息的进程在不同的内核上运行,我认为内核之间的同步可能是延迟的原因。有没有办法找出哪些进程在哪些内核上运行,或者如何控制哪些进程在哪些内核上运行? 有没有办法找出哪些进程在哪些内核上运行,或者如何控制哪些进程在哪些内核上运行 我不知道如何查看哪些进程位于哪个CPU/调度程序上,但在Observer中,可以查看调度程序的利用率 如果运行:observer.start,可以在“负载图表”选项卡

我用Elixir制作了一个多进程插入排序程序。但是,在32核机器上运行时,它比单进程插入排序慢。 如果发送消息的进程在不同的内核上运行,我认为内核之间的同步可能是延迟的原因。有没有办法找出哪些进程在哪些内核上运行,或者如何控制哪些进程在哪些内核上运行?

有没有办法找出哪些进程在哪些内核上运行,或者如何控制哪些进程在哪些内核上运行

我不知道如何查看哪些进程位于哪个CPU/调度程序上,但在Observer中,可以查看调度程序的利用率


如果运行:observer.start,可以在“负载图表”选项卡下查看。顶部的图表显示了一段时间内每个调度器的利用率。如果一个进程被过度利用,而另一个进程被未充分利用,您将看到它。

我猜您可以通过BEAM虚拟机控制并监视它-可能值得一看您可以使用erlang:system\u infoscheduler\u id检查当前进程运行的调度程序。请注意,调度程序可能会在核心之间移动,除非它们被绑定,使用和其他标志。我相信您可以通过命令行限制Elixir将使用的处理器数量。检查+A和+P标志。查看有关这些标志的更多详细信息。老实说,至于哪个内核正在运行哪个进程,答案是你不应该在意。我对一种假设性能取决于哪个内核正在运行哪个进程的方法非常谨慎。@OnorioCatenacci在对一个大列表运行程序时,我使用+P选项来增加进程数。但是,不使用+A选项。线程的数量意味着什么?@Legossia你的回答对我很有帮助。通过递归调用重复调用的进程是否可能在每次调用时移动调度程序?如果是,有没有办法将进程锁定到特定的调度程序?
defmodule Insertion do
  def insert(l, x) do
    case l do
      [h | hs] -> if x < h, do: [x | l], else: [h | insert(hs, x)]
      [] -> [x]
      _ -> inspect l
    end
  end

  def insertion_sort(l, x, []) do
    insert(l, x)
  end

  def insertion_sort(l, x, [y | ys]) do
    insert(l, x)
    |> insertion_sort(y, ys)
  end

  def sort(l) do
    case l do
      [] -> l
      [_] -> l
      [x | [y | xs]] -> insertion_sort([y], x, xs)
    end
  end


  #
  # Parallel
  #

  def send_to_next(x, y, :end) do
    insert_par(x, spawn(Insertion, :insert_par, [y, :end]))
  end

  def send_to_next(x, y, p) do
    send p, y
    insert_par(x, p)
  end

  def insert_par(x, next) do
    receive do
      {:ret, p} -> send p, {x, next}
      y -> if x < y, do: send_to_next(x, y, next), else: send_to_next(y, x, next)
    end
  end

  def insertion_sort_par([], _) do

  end

  def insertion_sort_par([x | xs], p) do
    send p, x
    insertion_sort_par(xs, p)
  end

  def ret_val(l, p) do
    send p, {:ret, self()}
    receive do
      {x, :end} -> [x | l]
      {x, next} -> ret_val([x | l], next)
    end
  end

  def sort_par([]) do
    []
  end

  def sort_par([x | xs]) do
    root = spawn(Insertion, :insert_par, [x, :end])
    IO.puts inspect :timer.tc(Insertion, :insertion_sort_par, [xs, root])
    ret_val([], root)
    |> Enum.reverse
  end

  def run(n) do
    x = floor :math.pow(10, n)
    l = Enum.map(1..x, fn _ -> floor :rand.uniform * x end)
    :timer.tc(Insertion, :sort_par, [l])
    |> inspect
    |> IO.puts
  end

end