0

在 i7-2960xm(4 核超线程)上试验多线程时,我遇到的 Groovy Gpars 的性能比预期的要差。在我的测试中,我一直在使用递归 fib 计算器来模拟工作负载:

def fibRecursive(int index) {
    if (index == 0 || index == 1) {
        return index
    }
    else {
        return fibRecursive(index - 2) + fibRecursive(index - 1)
    }
}

为了测试 Gpars,我目前正在使用以下代码:

def nums = [36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36, 36]

GParsPool.withPool(4) {
    nums.eachParallel {
        SplitTimer internalTimer = new SplitTimer()
        println("fibRecursive(${it}): ${fibRecursive(it)}")
        internalTimer.split("fibRecursive(${it})")

        for (instance in internalTimer.splitTimes) {
            println(instance)
        }
    }
}

并行计算fib(36)大约需要 1.9 秒withPool(4)withPool(1)大约需要 1.4 秒,我认为这有点类似于在 Gpars 之外调用函数,但只需要 0.4 秒,例如:

nums.each {
    SplitTimer internalTimer = new SplitTimer()
    println("fibRecursive(${it}): ${fibRecursive(it)}")
    internalTimer.split("fibRecursive(${it})")

    for (instance in internalTimer.splitTimes) {
        println(instance)
    }
}

有人可以解释为什么我可能会遇到这种性能下降吗?谢谢!

这是我的 SplitTimer 以防万一:

class SplitTimer {
    long initialTime
    int instances = 0

    class Instance {
        int index
        String name
        long time

        def elapsed() {
            return time - initialTime
        }

        def Instance(String instanceName) {
            this.index = this.instances++
            this.name = instanceName
            this.time = System.nanoTime()
        }

        String toString() {
            return "[Instance ${this.index}: \"${this.name}\" (${Formatter.elapsed(this.elapsed())} elapsed)]"
        }
    }

    def splitTimes = []

    def SplitTimer() {
        def initialInstance = new Instance("Start")
        this.initialTime = initialInstance.time
        splitTimes.add(initialInstance)
    }

    def split(String instanceName) {
        splitTimes.add(new Instance(instanceName))
    }
}

class Formatter {
    static int hours
    static int minutes
    static int seconds
    static int nanoseconds

    static setValues(time) {
        nanoseconds = time % 10**9

        seconds = time / 10**9
        minutes = seconds / 60
        hours = minutes / 60

        seconds %= 60
        minutes %= 60
    }

    static elapsed(time) {
        setValues(time)
        return "${hours}:" + "${minutes}:".padLeft(3, "0") + "${seconds}.".padLeft(3, "0") + "${nanoseconds}".padLeft(9,"0")
    }

    static absolute(time) {
        setValues(time)
        hours %= 24
        return "${hours}:".padLeft(3, "0") + "${minutes}:".padLeft(3, "0") + "${seconds}.".padLeft(3, "0") + "${nanoseconds}".padLeft(9,"0")
    }
}
4

1 回答 1

0

并行化少量函数调用所需的工作量可能比顺序运行它们所需的工作量要多。但是,如果您用非常大的数字调用斐波那契,这可能会改变。

于 2017-11-04T06:08:38.657 回答