如果参数大小大于8192,为什么numpy.sin会返回不同的结果?

问题描述 投票:14回答:1

我发现numpy.sin在参数大小<= 8192且大于8192时表现不同。不同之处在于性能和返回的值。有人可以解释这个效果吗?

例如,让我们计算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 ++ std::sin(Visual Studio 2017,Win32平台)给出0.7071067811865475;
  • C ++ std::sin(Visual Studio 2017,x64平台)给出0.70710678118654756;
  • math.sin给出了0.7071067811865476,这是合乎逻辑的,因为我使用的是64位Python。

我在NumPy文档中找不到任何解释,也没在其代码中找到任何解释。

更新#2:很难相信,但用sin取代sqrt就是这样:

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

更新:np.show_config()输出:

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']
python numpy anaconda intel-mkl
1个回答
3
投票

正如@WarrenWeckesser所写,“它几乎肯定是Anaconda和英特尔MKL问题;参见https://github.com/numpy/numpy/issues/11448https://github.com/ContinuumIO/anaconda-issues/issues/9129”。

不幸的是,在Windows下解决问题的唯一方法是卸载Anaconda并使用另一个发行版与MKL-​​free numpy。我使用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(在n = 8192为67.1μs)和np.sqrt(xx)为0.8862269254527579(16.4μs)。有点慢,但完全可重复。

© www.soinside.com 2019 - 2024. All rights reserved.