我发现,当参数大小numpy.sin的行为不同。不同之处在于性能和返回的值。有人能解释这种影响吗?
例如,让我们计算sin(pi/4):
x = np.pi*0.25
for n in range(8191, 8195):
xx = np.repeat(x, n)
%timeit np.sin(xx)
print(n, np.sin(xx)[0])
64.7 µs ± 194 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
8191 0.7071067811865476
64.6 µs ± 166 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
8192 0.7071067811865476
20.1 µs ± 189 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
8193 0.7071067811865475
21.8 µs ± 13.4 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
8194 0.7071067811865475
在通过8192个元素限制后,计算速度将提高3倍以上,并给出不同的结果:最后一个数字变为5而不是6。
当我试图用其他方法计算相同的值时,我得到:
C++cc>(Visual Studio 2017,Win32平台)给出0.7071067811865475;
C++cc>(Visual Studio 2017,X64平台)0.7071067811865475;
std::sin
给出0.7071067811865476,这是合乎逻辑的,因为我使用了64位Python。我在numpy文档和它的代码中找不到任何解释。
更新2:很难相信,但是用
std::sin
替换math.sin
给出了:44.2 µs ± 751 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
8191 0.8862269254527579
44.1 µs ± 543 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
8192 0.8862269254527579
10.3 µs ± 105 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
8193 0.886226925452758
10.4 µs ± 4.41 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
8194 0.886226925452758
更新:
sin
输出:mkl_info:
libraries = ['mkl_rt']
library_dirs = ['C:/GNU/Anaconda3\\Library\\lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl', 'C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl\\include', 'C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl\\lib', 'C:/GNU/Anaconda3\\Library\\include']
blas_mkl_info:
libraries = ['mkl_rt']
library_dirs = ['C:/GNU/Anaconda3\\Library\\lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl', 'C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl\\include', 'C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl\\lib', 'C:/GNU/Anaconda3\\Library\\include']
blas_opt_info:
libraries = ['mkl_rt']
library_dirs = ['C:/GNU/Anaconda3\\Library\\lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl', 'C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl\\include', 'C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl\\lib', 'C:/GNU/Anaconda3\\Library\\include']
lapack_mkl_info:
libraries = ['mkl_rt']
library_dirs = ['C:/GNU/Anaconda3\\Library\\lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl', 'C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl\\include', 'C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl\\lib', 'C:/GNU/Anaconda3\\Library\\include']
lapack_opt_info:
libraries = ['mkl_rt']
library_dirs = ['C:/GNU/Anaconda3\\Library\\lib']
define_macros = [('SCIPY_MKL_H', None), ('HAVE_CBLAS', None)]
include_dirs = ['C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl', 'C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl\\include', 'C:\\Program Files (x86)\\IntelSWTools\\compilers_and_libraries_2019.0.117\\windows\\mkl\\lib', 'C:/GNU/Anaconda3\\Library\\include']
最佳答案
正如@warrenweckesser所写,“几乎可以肯定这是一个蟒蛇和英特尔MKL问题;cf.https://github.com/numpy/numpy/issues/11448和https://github.com/ContinuumIO/anaconda-issues/issues/9129”。
不幸的是,在Windows下解决这个问题的唯一方法是卸载anaconda并使用另一个带有mkl freenumpy
的发行版。我使用了来自https://www.python.org/的python-3.6.6-amd64,并通过pip
安装了所有其他组件,包括numpy 1.14.5。我甚至设法使Spyder工作(不得不将Pyqt5降级到5.11.3,它拒绝在大于5.12时启动)。
现在,np.sin(xx)
始终为0.7071067811865476(67.1微秒atn = 8192
)和np.sqrt(xx)
0.8862269254275279(16.4微秒)。有点慢,但完全可以复制。
关于python - 如果参数大小大于8192,为什么numpy.sin会返回不同的结果?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55341055/