Functional programming 函数式编程中的递归不会提供高并发性。对吗?

Functional programming 函数式编程中的递归不会提供高并发性。对吗?,functional-programming,Functional Programming,我不熟悉函数式编程。命令式编程中的循环取代了FP中的递归。另一个语句是FP提供了高并发性。由于数据不可变,在多核/cpu系统上并行执行的指令 而在递归中,由于步骤的执行依赖于前面的步骤结果,因此无法并行执行步骤 因此,我假设FP中的递归不会提供高并发性。我说得对吗 不确定,如果我对你的理解是正确的,但这通常取决于你想要完成什么 仅一个递归不能并行执行其子循环。但是可以在同一个数据集上使用两个递归。i、 e.通过两个并发运行的递归函数同时处理从左到右的数组。这(两)个功能可以(因此)并行运行 详细

我不熟悉函数式编程。命令式编程中的循环取代了FP中的递归。另一个语句是FP提供了高并发性。由于数据不可变,在多核/cpu系统上并行执行的指令

而在递归中,由于步骤的执行依赖于前面的步骤结果,因此无法并行执行步骤


因此,我假设FP中的递归不会提供高并发性。我说得对吗

不确定,如果我对你的理解是正确的,但这通常取决于你想要完成什么

仅一个递归不能并行执行其子循环。但是可以在同一个数据集上使用两个递归。i、 e.通过两个并发运行的递归函数同时处理从左到右的数组。这(两)个功能可以(因此)并行运行

详细地说,只要有一个函数可以自己运行,那么递归函数或内部有循环的函数都无关紧要。关于你的问题:


不,每个定义的递归函数不提供任何并发性。

某种程度上。执行并行度不能超过数据并行度;这是。然而,无论是函数式的还是命令式的,您的数据并行性通常都比典型的顺序算法要高。例如,考虑向量的标量倍数:(注:这是一些组成的Algl风格语言):

这仍然是一个顺序算法

但是,您可以注意到,不存在数据依赖关系——实际上,您不需要使用之前/之后的乘法结果来计算后面的乘法。因此,我们在这里有并行化的潜力。这可以通过命令式语言实现:

function scalar_multiple(scalar c, vector v) {
    vector v1;
    parallel_for (int i in 0..length(v)-1) {
        v1[i] = c * v[i];
    }
    return v1;
}
但是这种的并行是一种危险的构造。考虑搜索功能:

function first(predicate p, vector v) {
    for (int i = 0; i < length(v); i++) {
        if (p(v[i])) return i;
    }
    return -1;
}
现在我们不必返回满足条件的第一个元素的索引,只返回满足条件的元素。我们通过并行化打破了函数的契约

显而易见的解决方案是“不允许
返回
内部
并行”
。但是还有很多其他危险的构造;事实上,您会注意到我不得不放弃C风格的
for
循环,因为增量和测试模式本身在并行语言中是危险的。考虑:

function sequence(int n) {
    vector v;
    int c = 0;
    parallel_for (int i = 0..n-1) {
        v[i] = c++;
    }
    return v;
}
这又是一个“玩具”示例(“只需使用
v[i]=i;
!”),但它说明了这一点:由于并行性,此函数以随机顺序初始化
v
。因此,在类似
parallel\u for
的结构中使用的“安全”结构恰恰是纯函数式语言中允许的结构,这使得向这些语言添加并行结构比向命令式语言添加并行结构更“安全”


这只是一个非常简单的例子;当然,真正的并行需要找到比这更大的工作块来并行化

循环比直接递归更频繁地被高阶函数替换。递归是函数编程中的一种总括性度量,用于在需要执行的高阶函数还不存在的情况下进行度量

例如,如果要在列表的所有元素上运行相同的计算,可以使用高度并行的
映射。查找满足特定条件的元素是一个过滤器,也是高度并行的


有些算法只是简单地需要上一次迭代的结果才能继续。这些函数往往需要递归函数,您是对的,它们通常不容易实现高度并发。

这实际上取决于具体的实现。优化编译器不能将递归表示的内容转换为迭代或并行过程,这并没有一般规则。
function first(predicate p, vector v) {
    for (int i = 0; i < length(v); i++) {
        if (p(v[i])) return i;
    }
    return -1;
}
function first(predicate p, vector v) {
    parallel_for (int i in 0..length(v)-1) {
        if (p(v[i])) return i;
    }
    return -1;
}
function sequence(int n) {
    vector v;
    int c = 0;
    parallel_for (int i = 0..n-1) {
        v[i] = c++;
    }
    return v;
}