Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么np.float32的执行速度可能比np.float64慢?_Python_Performance_Numpy_Linear Algebra - Fatal编程技术网

Python 为什么np.float32的执行速度可能比np.float64慢?

Python 为什么np.float32的执行速度可能比np.float64慢?,python,performance,numpy,linear-algebra,Python,Performance,Numpy,Linear Algebra,我正在根据POT的githubrepo的实现,为最优传输问题编写自己的Sinkhorn-Knopp算法实现。该函数如下所示: #version for the dense matrices def sinkhorn_knopp(C, reg, a = None, b = None, max_iter = 1e3, eps = 1e-9, log = False, verbose = False, log_interval = 10): a = np.asarray(a, dtype=np.fl

我正在根据POT的
github
repo的实现,为最优传输问题编写自己的
Sinkhorn-Knopp
算法实现。该函数如下所示:

#version for the dense matrices
def sinkhorn_knopp(C, reg, a = None, b = None, max_iter = 1e3, eps = 1e-9, log = False, verbose = False, log_interval = 10):

a = np.asarray(a, dtype=np.float64)
b = np.asarray(b, dtype=np.float64)
C = np.asarray(C, dtype=np.float64)

# if the weights are not specified, assign them uniformly
if len(a.shape) == 0:
     a = np.ones((C.shape[0],), dtype=np.float64) / C.shape[0]
if len(b.shape) == 0:
     b = np.ones((C.shape[1],), dtype=np.float64) / C.shape[1]       

# Faster exponent
K = np.divide(C, -reg)
K = np.exp(K)

# Init data
dim_a = len(a)
dim_b = len(b)

# Set ininital values of u and v
u = np.ones(dim_a) / dim_a
v = np.ones(dim_b) / dim_b

r = np.empty_like(b)
Kp = (1 / a).reshape(-1, 1) * K
err = 1
cpt = 0

if log:
    log = {'err' : []}

while(err > eps and cpt < max_iter):
    uprev = u
    vprev = v
    
    KtransposeU = K.T @ u
    v = np.divide(b, KtransposeU)
    u = 1. / (Kp @ v)
    
    if (np.any(KtransposeU == 0)
            or np.any(np.isnan(u)) or np.any(np.isnan(v))
            or np.any(np.isinf(u)) or np.any(np.isinf(v))):
        # we have reached the machine precision
        # come back to previous solution and quit loop
        print('Warning: numerical errors at iteration', cpt)
        u = uprev
        v = vprev
        break
    if cpt % log_interval == 0:
        #residual on the iteration
        r = (u @ K) * v 
        # violation of marginal
        err = np.linalg.norm(r - b)  
        
        if log:
            log['err'].append(err)
    cpt += 1
             
#return OT matrix
ot_matrix = u * K * v
loss = np.sum(C * ot_matrix)
if log:
    return ot_matrix, loss, log
else:
    return ot_matrix, loss 

对于更大的问题,时间上的差异几乎是时间上的,这看起来相当奇怪。为什么会这样?

您的计算机是否足够新,可以拥有64位总线和处理器?@hpaulj是的,确实如此。那么,为了使用$32$位算术计算某些东西,需要以某种方式将其转换为$64$位处理器,这样会产生额外的开销吗?奇怪的是,差距随着问题的大小而增大。对于较小的问题,差距没有较大的问题那么大。您是否检查了所有中间结果,以查看是否在后台进行了不需要的类型转换?但即使是这样,也可能有一些函数在执行任何操作之前将所有内容强制转换到float64内部。也许在这两个函数上运行探查器也可以提示这种行为的原因。您的计算机是否足够新,可以拥有64位总线和处理器?@hpaulj是的,就是这样。那么,为了使用$32$位算术计算某些东西,需要以某种方式将其转换为$64$位处理器,这样会产生额外的开销吗?奇怪的是,差距随着问题的大小而增大。对于较小的问题,差距没有较大的问题那么大。您是否检查了所有中间结果,以查看是否在后台进行了不需要的类型转换?但即使是这样,也可能有一些函数在执行任何操作之前将所有内容强制转换到float64内部。也许在这两个函数上运行探查器也可以提示这种行为的原因。
#np.float64 version
63.6 ms ± 7.94 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
#np.float32 version
71.4 ms ± 2.01 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

#np.float64 version
650 ms ± 12.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
#np.float32 version
2.48 s ± 298 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)