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

时间:2019-06-26 08:23:00

标签: performance parallel-processing erlang elixir beam

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

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

enter image description here

1 个答案:

答案 0 :(得分:1)

  

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

我不知道查看哪个进程位于哪个CPU /调度程序上的方法,但是在Observer中可以看到调度程序利用率。

如果运行:observer.start(),则可以在“加载图表”标签下查看。上方的图表显示了每个调度程序随时间的利用率。如果其中一个被过度利用,而另一个未被充分利用,您将在这里看到它。