我制作了这个光线追踪器来模拟两个镜头。每次光线到达屏幕时,都会对该屏幕上的位置进行投票。但是,这种运行速度很慢。它与光线跟踪器无关,只是光线的数量(128 ^ 4)。我知道多线程不会为此工作,但我如何使用多处理来为屏幕上的像素投票。这让我大吃一惊 - 我如何让每个孩子投票给一个像素。每条射线都是独立的。这是一些示例代码。创建输入数据也存在问题。只需要将一组光线发送到多处理类就需要很长时间。
基本上,我希望内部循环产生最多8个子进程 - 让这些子进程投票 - 然后释放一个插槽......我认为即使这样也会运行缓慢。
import numpy as np
from mpl_toolkits.mplot3d import Axes3D
from matplotlib import cm
from matplotlib.ticker import LinearLocator, FormatStrFormatter
import matplotlib.pyplot as plt
from matplotlib.mlab import griddata
from matplotlib import cm
import random
A = 0
B = 0
C = 0
D = 0
E_initial = np.zeros((512,512))
while A <= 50:
B = 0
while B <= 50:
C = 0
while C <= 50:
D = 0
while D <= 50:
#Ray tracing here
x_contact = random.randint(0,511)
y_contact = random.randint(0,511)
E_initial[x_contact,y_contact] += 1
D = D + 1
C = C +1
B = B + 1
print A
A = A + 1
fig = plt.figure()
ax = fig.add_subplot(111)
plt.imshow(E_initial)
cbar = plt.colorbar(orientation='vertical')
cbar.set_label('# of contacts', rotation=270, labelpad=10)
plt.show()
答案 0 :(得分:3)
在尝试多处理之前,请注意您可以消除四重while循环 通过利用一些numpy功能。
indices = np.random.randint(0, 512**2, size=(50**4))
生成0(包括)和512 ** 2(不包括)之间的随机索引位置。
每个索引位置对应于E_initial
中的位置。
然后,您可以使用np.bincount
来计算每个索引位置发生的次数。
np.bincount
返回的数组大小为512 ** 2,并且每个位置都包含一个整数计数,对应于索引位置在indices
中出现的次数。但是啊 - 这基本上就是我们希望E_initial
平等的。
import numpy as np
import matplotlib.pyplot as plt
indices = np.random.randint(0, 512**2, size=(50**4))
E_initial = np.bincount(indices).reshape((512, 512))
fig = plt.figure()
ax = fig.add_subplot(111)
plt.imshow(E_initial)
cbar = plt.colorbar(orientation='vertical')
cbar.set_label('# of contacts', rotation=270, labelpad=10)
plt.show()
PS。有8个进程修改一个数组将会很慢,因为在分配期间必须锁定数组以避免导致错误结果的竞争条件。必须锁定每个分配将使多处理代码比等效的单进程代码慢得多。
PPS。虽然
E_initial[x_contact,y_contact] += 1
是某些语言(如C语言)的标准做法,在使用NumPy数组时,它在Python中死得很慢。它很慢,因为每个赋值涉及至少三个Python函数调用(__getitem__
,__iadd__
,__setitem__
)。如果你把它放在四重循环中,你会得到(至少)3 * 50 ** 4个Python函数调用。如果你可以将所有Python调用减少到一个NumPy函数调用,那么你将获得巨大的性能提升。因此,如果可能的话,尽量避免将值分配给NumPy数组中的各个位置!要利用NumPy,您希望最小化函数调用和循环的数量,并尽可能少地调用NumPy函数来最大化工作量。这通常意味着形成一个大数组并将整个事物推入NumPy函数中,该函数在C或Fortran中进行计算。