我正在比較Julia計算3D空間中兩組點之間的歐幾里德距離與C中的等效實現之間的距離。驚訝地看到,(對於這種特殊情況下,我的具體實現)Julia是比C快22%。當我還包括在朱莉婭版本@fastmath
,這將是比C爲什麼我的Julia實現用於計算3D中的歐幾里德距離比我的C實現更快
這導致更快的甚至83%對我的問題:爲什麼?無論是朱莉婭比我原本想象的更加神奇或我在C做的事情效率非常低。我打賭我的錢在後者上。
有關實施細節的一些:
- 在朱莉婭我用的
Float64
二維數組。 - 在C中,我使用動態分配的
double
的一維數組。 - 在C中,我使用
math.h
中的sqrt
函數。 - 計算速度非常快,因此我計算它們1000倍以避免在微/毫秒級別進行比較。
- 編譯器:GCC 5.4.0
- 優化標誌:
-O3 -ffast-math
時序:
- 朱莉婭(不
@fastmath
)
關於編譯的一些細節:90 s
- 朱(與
@fastmath
):20秒 - C:116章第
- 我使用bash命令
time
用於定時$ time ./particleDistance.jl
(與認領在文件)$ time ./particleDistance
particleDistance.j升
#!/usr/local/bin/julia
function distance!(x::Array{Float64, 2}, y::Array{Float64, 2}, r::Array{Float64, 2})
nx = size(x, 1)
ny = size(y, 1)
for k = 1:1000
for j = 1:ny
@fastmath for i = 1:nx
@inbounds dx = y[j, 1] - x[i, 1]
@inbounds dy = y[j, 2] - x[i, 2]
@inbounds dz = y[j, 3] - x[i, 3]
rSq = dx*dx + dy*dy + dz*dz
@inbounds r[i, j] = sqrt(rSq)
end
end
end
end
function main()
n = 4096
m = 4096
x = rand(n, 3)
y = rand(m, 3)
r = zeros(n, m)
distance!(x, y, r)
println("r[n, m] = $(r[n, m])")
end
main()
particleDistance.c
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
void distance(int n, int m, double* x, double* y, double* r)
{
int i, j, I, J;
double dx, dy, dz, rSq;
for (int k = 0; k < 1000; k++)
{
for (j = 0; j < m; j++)
{
J = 3*j;
for (i = 0; i < n; i++)
{
I = 3*i;
dx = y[J] - x[I];
dy = y[J+1] - x[I+1];
dz = y[J+2] - x[I+2];
rSq = dx*dx + dy*dy + dz*dz;
r[j*n+i] = sqrt(rSq);
}
}
}
}
int main()
{
int i;
int n = 4096;
int m = 4096;
double *x, *y, *r;
size_t xbytes = 3*n*sizeof(double);
size_t ybytes = 3*m*sizeof(double);
x = (double*) malloc(xbytes);
y = (double*) malloc(ybytes);
r = (double*) malloc(xbytes*ybytes/9);
for (i = 0; i < 3*n; i++)
{
x[i] = (double) rand()/RAND_MAX*2.0-1.0;
}
for (i = 0; i < 3*m; i++)
{
y[i] = (double) rand()/RAND_MAX*2.0-1.0;
}
distance(n, m, x, y, r);
printf("r[n*m-1] = %f\n", r[n*m-1]);
free(x);
free(y);
free(r);
return 0;
}
的Makefile
all: particleDistance.c
gcc -o particleDistance particleDistance.c -O3 -ffast-math -lm
你如何以及在哪裏測量你的時間,我認爲函數rand()具有很高的成本。 –
我從命令行計時,所以我正在計時整個程序,而不僅僅是它的一部分。所以我的時間安排包括花費在rand()上的時間(Julia和C)。我也在註釋掉rand()後做了時間表。時間稍短,但Julia仍然快得多。 – mtgoncalves
可能你與C和茱莉亞的軟數學聯繫在一起使用fpu –