为什么从F#调用我的C代码非常慢(与本机相比)?
问题描述:
所以我写了一些数字代码在C,但想从F#调用它。然而它运行得非常慢。为什么从F#调用我的C代码非常慢(与本机相比)?
时报:
- GCC -O3:4秒
- GCC -O0:30秒
- fsharp代码调用优化GCC代码:2分30秒。
作为参考,C代码是
int main(int argc, char** argv)
{
setvals(100,100,15,20.0,0.0504);
float* dmats = malloc(sizeof(float) * factor*factor);
MakeDmat(1.4,-1.92,dmats); //dmat appears to be correct
float* arr1 = malloc(sizeof(float)*xsize*ysize);
float* arr2 = malloc(sizeof(float)*xsize*ysize);
randinit(arr1);
for (int i = 0;i < 10000;i++)
{
evolve(arr1,arr2,dmats);
evolve(arr2,arr1,dmats);
if (i==9999) {print(arr1,xsize,ysize);};
}
return 0;
}
我离开了的功能的实现。我正在使用的F#代码是
open System.Runtime.InteropServices
open Microsoft.FSharp.NativeInterop
[<DllImport("a.dll")>] extern void main (int argc, char* argv)
[<DllImport("a.dll")>] extern void setvals (int _xsize, int _ysize, int _distlimit,float _tau,float _Iex)
[<DllImport("a.dll")>] extern void MakeDmat(float We,float Wi, float*arr)
[<DllImport("a.dll")>] extern void randinit(float* arr)
[<DllImport("a.dll")>] extern void print(float* arr)
[<DllImport("a.dll")>] extern void evolve (float* input, float* output,float* connections)
let dlimit,xsize,ysize = 15,100,100
let factor = (2*dlimit)+1
setvals(xsize,ysize,dlimit,20.0,0.0504)
let dmat = Array.zeroCreate (factor*factor)
MakeDmat(1.4,-1.92,&&dmat.[0])
let arr1 = Array.zeroCreate (xsize*ysize)
let arr2 = Array.zeroCreate (xsize*ysize)
let addr1 = &&arr1.[0]
let addr2 = &&arr2.[0]
let dmataddr = &&dmat.[0]
randinit(&&dmat.[0])
[0..10000] |> List.iter (fun _ ->
evolve(addr1,addr2,dmataddr)
evolve(addr2,addr1,dmataddr)
)
print(&&arr1.[0])
F#代码是在优化上编译的。
调用C代码的单一接口真的很慢(每个函数调用的开销几乎为8ms)还是我只是在做一些愚蠢的事情?
答
看起来是问题的一部分是,你正在使用的F#和PInvoke的签名的C面都float
。在F#float
实际上是System.Double
,因此是8个字节。在C a float
通常是4个字节。
如果是这样的CLR下运行我希望你看到的PInvoke在调试过程中堆栈不平衡错误。我不确定莫诺是否有类似的检查。但这可能与您看到的问题有关。
测试在Windows的代码?可能是很多事情。 – leppie 2012-03-14 05:18:33
另外:在F#中,'float'的意思是'double',它是8个字节。在C中,通常'float'是4个字节。您可能会遇到一个严重的签名不匹配问题。 – JaredPar 2012-03-14 05:18:51
@JaredPar - 这就是答案,我怀疑浮点数转换会导致参数被更改为导致执行速度更慢的参数。 F#的运行时间现在几乎与普通的C相同。是否有一些方法来检查这些签名不匹配? – 2012-03-14 05:29:31