Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
F# 以x64为目标有时会导致比任何CPU都差的性能_F# - Fatal编程技术网

F# 以x64为目标有时会导致比任何CPU都差的性能

F# 以x64为目标有时会导致比任何CPU都差的性能,f#,F#,这是两个函数,fun1接受1个参数,fun2接受4个额外的无用参数。当我针对x64时,fun1需要4秒,但fun2需要不到1秒。如果我的目标是任何CPU,那么这两个都需要不到1秒的时间 我在这里问了一个类似的问题 它是在.Net 4.5 Visual Studio 2012 F#3.0中编译的,在windows 7 x64中运行 open System open System.Diagnostics type Position = { a: int b

这是两个函数,
fun1
接受1个参数,
fun2
接受4个额外的无用参数。当我针对x64时,
fun1
需要4秒,但
fun2
需要不到1秒。如果我的目标是任何CPU,那么这两个都需要不到1秒的时间

我在这里问了一个类似的问题

它是在.Net 4.5 Visual Studio 2012 F#3.0中编译的,在windows 7 x64中运行

open System
open System.Diagnostics

type Position =
    {
        a: int
        b: int
    }

[<EntryPoint>]
let main argv = 

    let fun1 (pos: Position[]) =  //<<<<<<<< here
        let functionB x y z = 4

        Array.fold2 (fun acc x y -> acc + int64 (functionB x x y)) 0L pos pos

    let fun2 (pos: Position[]) u v w x =  //<<<<<<<< here
        let functionB x y z = 4

        Array.fold2 (fun acc x y -> acc + int64 (functionB x x y)) 0L pos pos



    let s = {a=2;b=3}
    let pool = [|s;s;s|]

    let test1 n =
        let mutable x = 0L
        for i in 1 .. n do
            x <- fun1 pool

    let test2 n =
        let mutable x = 0L
        for i in 1 .. n do
            x <- fun2 pool 1 2 3 4

    let sw = new Stopwatch()
    sw.Start()
    test2 10000000
    sw.Stop()
    Console.WriteLine(sw.Elapsed)

    sw.Restart()
    test1 10000000
    sw.Stop()
    Console.WriteLine(sw.Elapsed)


    0 // return an integer exit code
开放系统
开放系统诊断
类型位置=
{
a:整数
b:int
}
[]
让主argv=

让fun1(pos:Position[])=/这种差异几乎可以肯定是紧张的一种怪癖。这也解释了不一致的结果。这是像这样的微观基准测试的常见问题。执行一个或多个冗余的方法执行,以便在幕后编译整个过程,并计时最后一个过程。它们将是相同的

由于这种怪癖,你可能会得到比这更奇怪的结果。

这不是一个完整的答案,这是对问题的第一次诊断

我可以用相同的配置重现这种行为。如果在
Tools->Options->F#Tools->F#Interactive
中打开F#Interactive 64位,您可以在那里观察到相同的行为

与之不同,x64抖动不是问题。事实证明,与
test2
相比,项目属性中的“生成尾部调用”选项会导致
test1
的速度大大降低。如果关闭该选项,则两个案例的速度相似

另一方面,您可以在
fun1
上使用
inline
关键字,这样就不需要尾部调用。无论
fun2
是否内联,这两个示例在执行时间上都具有可比性


这就是说,将
tail.
opcode添加到
fun1
会使它比(使用
fun2
执行相同操作)慢得多,这很奇怪。您可以联系F#团队进行进一步调查。

我可以用VS2012 RTM重新编程–您的第一个代码大约需要4秒,第二个代码<1秒。而且,它确实需要额外的四个参数才能有任何差异;添加三个额外的参数仍然需要约4秒。有趣的是,没有明显的加速原因-我比较了反汇编,它是相同的,但在第二种情况下,添加了更多的指令来加载额外的参数,我本以为这会减慢速度。奇怪。它们对我来说几乎是一样的(~4)…事实上,第二个总是需要更长的头发。(VS2012 RTM.NET 4.5)是您的F#项目设置为“类库”的输出类型吗?@Daniel:我的复制是作为一个独立的x64应用程序完成的(没有C#,没有类库)。也许这是x64的病理情况,而x86可以吗?你的测试是x64吗?