10

我正在使用 R 来转换一些 shapefile。R 仅使用我的处理器的一个核心来完成此操作,我想使用并行处理来加速它。所以我已经像这样并行化了这个过程。

鉴于files这是要转换的文件列表:

library(doMC)
registerDoMC()

foreach(f=files) %dopar% {
  # Code to do the conversion
}

这工作得很好,它使用 2 个内核。根据文档registerDoMC()默认情况下,该函数使用parallel包检测到的一半内核。

我的问题是为什么我应该使用一半的核心而不是所有的核心?(在本例中为 4 个核心。)通过使用该功能registerDoMC(detectCores()),我可以使用系统上的所有核心。如果有的话,这样做的缺点是什么?

4

5 回答 5

9

除了可扩展性的问题,还有一个简单的规则:英特尔超线程内核没有帮助,至少在 Windows 下是这样。所以我用 detectCores() 得到了 8 个,但是当超过 4 个内核时我从来没有发现改进,即使使用通常可以完美扩展的 MCMC 并行线程也是如此。

如果有人有一个案例(在 Windows 下),超线程有这样的改进,请发布。

于 2013-08-17T17:21:36.517 回答
8

任何时候进行并行处理都会有一些开销(这可能是不小的开销,尤其是在锁定数据结构和阻塞调用的情况下)。对于小批量作业,在单个内核或两个内核上运行要快得多,因为您无需支付该开销。

我不知道您的工作规模,但您可能应该进行一些扩展实验,将您的工作安排在 1 个处理器、2 个处理器、4 个处理器、8 个处理器上,直到达到系统的最大核心数(通常,你总是加倍处理器数量)。编辑:看起来您只使用 4 个内核,所以请使用 1、2 和 4。

为每个核心计数运行约 32 次试验的计时结果并获得置信区间,然后您可以确定在所有核心上运行是否适合您。如果您的工作需要很长时间,请将试验次数减少到 5 次左右,但请记住,更多的试验会给您更高的信心。

详细说明:

学生 t 检验

学生的 t 检验基本上说“您计算了此核心计数的平均时间,但这不是真正的平均值。如果我们有无限数量的数据点的平均值,我们只能得到真正的平均值。实际上,您计算的真实平均值位于您计算的平均值附近的某个区间”

然后,显着性 t 检验基本上比较了 2 个数据点的真实平均值周围的区间,并说明它们是否存在显着差异。所以你可能有一个平均时间比另一个少,但由于标准偏差足够高,我们不能肯定地说它实际上更少;真实平均值可能相同。

因此,要计算此检验的显着性:

  • 运行你的计时实验
  • 对于每个核心数:
  • 计算你的平均值和标准差。标准差应该是总体标准差,即总体方差的平方根总体方差 (1/N) * summation_for_all_data_points((datapoint_i - mean)^2)

现在您将获得每个核心计数的平均值和标准差:(m_1, s_1), (m_2, s_2) 等 - 对于每对核心计数: - 计算 t 值:t = (mean_1 - mean_2) /(s_1/ sqrt(#dataPoints))

我展示的示例 t 值测试核心计数为 1 的平均时序结果是否与核心计数为 2 的时序结果显着不同。您可以通过以下方式进行测试:

t = (m_2 - m_1)/(s_2/ sqrt(#dataPoints))

计算出这些 t 值后,您可以通过查看临界值表来判断它们是否显着。现在,在您点击它之前,您还需要了解 2 件事:

自由程度

这与您拥有的数据点数量有关。您拥有的数据点越多,平均值附近的间隔可能就越小。自由度可以衡量您计算出的平均值的移动能力,它是 #dataPoints - 1 (我提供的链接中的v )。

Α

Alpha 是一个概率阈值。在高斯(正态、钟形曲线)分布中,alpha 会在左侧和右侧切割钟形曲线。临界值中间的任何概率都落在阈值内,并且是一个微不足道的结果。较低的 alpha 使获得显着结果变得更加困难。即 alpha = 0.01 意味着只有前 1% 的概率是显着的,而 alpha = 0.05 意味着前 5% 的概率。大多数人使用 alpha = 0.05。

在我链接到的表中,1-alpha 决定了您将在哪一列中查找临界值。(所以 alpha = 0.05 给出 0.95,或 95% 的置信区间),而v是您的自由度,或要查看的行。

如果您的临界值小于计算的t(绝对值),那么您的结果并不显着。如果临界值大于您计算的t(绝对值),那么您具有统计显着性。

编辑:学生 t 检验假设被比较的两个平均值之间的方差和标准差相同。也就是说,它假设数据点在真实均值附近的分布是相等的。如果您不想做出这个假设,那么您正在寻找Welch's t-test,它略有不同。wiki 页面有一个很好的公式来计算这个测试的 t 值。

于 2013-08-17T16:14:34.970 回答
6

您要避免一种情况:

  • 将任务分散到所有 N 个核心上

  • 让每个核心使用诸如 OpenBLAS 或 MKL 之类的所有核心来完成任务

因为现在你有一个 N 乘 N 的争用:N 个任务中的每一个都希望将其线性代数工作分配给所有 N 个内核。

在多用户环境中提供了另一个(微不足道的)反例,其中并非机器上的所有 M 个用户都可以(同时)外包给 N 个内核。

于 2013-08-17T18:04:02.253 回答
4

不使用所有可用内核的另一个原因是,如果您的任务使用大量内存并且您没有足够的内存来支持该数量的工作人员。请注意,确定给定数量的内存可以支持多少工作人员可能很棘手,因为doMC使用mclapply哪个工作人员分叉,因此内存可以在工作人员之间共享,除非它被其中一个修改。

从这个问题的答案中可以清楚地看出,要确定要使用的正确工人数量并不总是那么容易。有人可能会争辩说不应该有默认值,并且应该强制用户指定数字,但我不确定我是否会走那么远。无论如何,使用一半数量的内核并没有什么神奇之处。

于 2013-08-18T02:26:33.337 回答
2

嗯。我不是并行处理专家,但我一直认为使用所有内核的不利之处在于,当您尝试其他任何事情时,它会使您的机器变得迟缓。当我使用所有内核时,我个人也遇到过这种情况,所以我现在的做法是在我做并行操作时使用我的 8 个内核中的 7 个,让我一个内核来做其他事情。

于 2013-08-17T22:06:19.457 回答