Her*_*ert 1 c++ numpy scipy python-3.x c++11
我有一个Matlab背景,当我一年前买了一台笔记本电脑时,我仔细选择了一台具有很多计算能力的机器,机器有4个线程,它为我提供了8个2.4GHz的线程.机器证明自己是非常强大的,并且使用简单的parfor-loops我可以利用所有的处理器线程,为了许多问题和实验,我的速度接近8.
这个美好的星期天我正在试验numpy,人们经常告诉我numpy的核心业务是使用libblas高效实现的,甚至可能使用多个内核和像OpenMP这样的库(使用OpenMP你可以使用c风格的pragma创建类似parfor的循环).
这是许多数值和机器学习算法的一般方法,你使用昂贵的高级操作(如矩阵乘法)表达它们,但是使用昂贵的高级语言(如Matlab和python)来提高舒适度.而且,c(++)允许我们绕过GIL.
所以很酷的部分是线性代数 - 东西应该在python中处理得非常快,无论何时使用numpy.你只需要一些函数调用的开销,但如果它背后的计算很大,那就可以忽略不计了.
因此,在没有触及主题的情况下,并非所有内容都可以用线性代数或其他numpy操作表达,我给了它一个旋转:
t = time.time(); numpy.dot(range(100000000), range(100000000)); print(time.time() - t)
40.37656021118164
Run Code Online (Sandbox Code Playgroud)
所以我,这40秒我看到我机器上8个线程中的一个工作100%,其他线程接近0%.我不喜欢这个,但即使有一个线程正在工作,我希望它能在大约0.something秒内运行.点积产生100M +'es和*'es,所以我们有2400M/100M =每秒24个时钟滴答,一个+,一个*和任何开销.
然而,对于+,*和开销,算法需要40*24 =约= 1000个滴答(!!!!!).我们在C++中这样做:
#include<iostream>
int main() {
unsigned long long result = 0;
for(unsigned long long i=0; i < 100000000; i++)
result += i * i;
std::cout << result << '\n';
}
Run Code Online (Sandbox Code Playgroud)
BLITZ:
herbert@machine:~$ g++ -std=c++11 dot100M.cc
herbert@machine:~$ time ./a.out
662921401752298880
real 0m0.254s
user 0m0.254s
sys 0m0.000s
Run Code Online (Sandbox Code Playgroud)
0.254秒,几乎比numpy.dot快100倍.
我想,也许python3范围生成器是缓慢的部分,所以我通过首先在std :: vector中存储所有100M数字(使用迭代push_back)而不是迭代它来阻碍我的c ++ 11实现.这个速度要慢得多,它花了不到4秒,仍然快了10倍.
我在ubuntu上使用'pip3 install numpy'安装了我的numpy,它开始编译一段时间,使用gcc和gfortran,而且我看到提到blas-header文件通过编译器输出.
出于什么原因numpy.dot如此极慢?
Dan*_*iel 12
所以你的比较是不公平的.在你的python示例中,首先生成两个范围对象,将它们转换为numpy-arrays,然后执行标量产品.计算至关重要.这是我的电脑的号码:
>>> t=time.time();x=numpy.arange(100000000);numpy.dot(x,x);print time.time()-t
1.28280997276
Run Code Online (Sandbox Code Playgroud)
没有阵列的生成:
>>> t=time.time();numpy.dot(x,x);print time.time()-t
0.124325990677
Run Code Online (Sandbox Code Playgroud)
完成后,C版需要大致相同的时间:
real 0m0.108s
user 0m0.100s
sys 0m0.007s
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
923 次 |
| 最近记录: |