【发布时间】:2026-01-14 22:05:01
【问题描述】:
这是我在 C++ 和 D 中比较并行性进行的一个实验。我使用相同的设计在两种语言中实现了一种算法(一种用于网络社区检测的并行标签传播方案):并行迭代器获取句柄函数(通常一个闭包)并将其应用于图中的每个节点。
这是 D 中的迭代器,使用来自 std.parallelism 的 taskPool 实现:
/**
* Iterate in parallel over all nodes of the graph and call handler (lambda closure).
*/
void parallelForNodes(F)(F handle) {
foreach (node v; taskPool.parallel(std.range.iota(z))) {
// call here
handle(v);
}
}
这是传递的句柄函数:
auto propagateLabels = (node v){
if (active[v] && (G.degree(v) > 0)) {
integer[label] labelCounts;
G.forNeighborsOf(v, (node w) {
label lw = labels[w];
labelCounts[lw] += 1; // add weight of edge {v, w}
});
// get dominant label
label dominant;
integer lcmax = 0;
foreach (label l, integer lc; labelCounts) {
if (lc > lcmax) {
dominant = l;
lcmax = lc;
}
}
if (labels[v] != dominant) { // UPDATE
labels[v] = dominant;
nUpdated += 1; // TODO: atomic update?
G.forNeighborsOf(v, (node u) {
active[u] = 1;
});
} else {
active[v] = 0;
}
}
};
C++11 实现几乎相同,但使用 OpenMP 进行并行化。那么缩放实验表明了什么?
在这里,我检查了弱缩放,将输入图大小加倍,同时将线程数加倍并测量运行时间。理想情况下应该是一条直线,但并行性当然会有一些开销。我在 main 函数中使用defaultPoolThreads(nThreads) 来设置 D 程序的线程数。 C++ 的曲线看起来不错,但 D 的曲线看起来非常糟糕。我做错了什么吗? D 并行性,或者这是否严重影响了并行 D 程序的可扩展性?
附言编译器标志
对于 D:rdmd -release -O -inline -noboundscheck
对于 C++:-std=c++11 -fopenmp -O3 -DNDEBUG
pps。一定是真的有问题,因为并行的 D 实现比顺序的慢:
pps。出于好奇,以下是两种实现的 Mercurial 克隆网址:
【问题讨论】:
-
不使用 openmp 时性能如何?
-
通过检查它看起来不像 dmd 编译器当前支持 openmp。如果一个版本使用 openmp 而另一个版本不使用,这对我来说似乎不是苹果对苹果的比较。
-
虚假分享,也许吧? en.wikipedia.org/wiki/False_sharing
-
可以试试在GDC下编译D程序吗?
-
我可以确认您的发现。我使用的线程越多,运行时间越长:平台 Win32。我知道您使用的是 64 位(因为我必须将一些 'long' 更改为 'size_t' 才能编译它)。你使用的是 Win 还是 Nix?
标签: c++ performance parallel-processing d