具有 mkl-dnn 后端性能的 pytorch 在具有多线程的小型 conv 上
pytorch with mkl-dnn backend performance on small conv with multi thread
我正在尝试使用 mkl-dnn 后端的 pytorch 模型。但是我遇到了一个问题,即多线程性能比预期的要慢,在小型转换上运行。请看这个 table。
mkl-dnn performace table
运行big conv,与单线程相比,8线程的性能明显更快。但是跑small conv,速度和8线程和单线程没有太大区别。
所以我的问题是:
1.为什么8个线程没有明显快于1个小conv的线程?
2. 如何提高8线程在small conv上的性能?
我的代码在这里
import time
import torch
import torch.nn as nn
from torch.nn.utils import weight_norm
class MyConv(nn.Module):
def __init__(self, *args, **kwargs):
super().__init__()
self.cell = nn.Conv1d(*args, **kwargs)
self.cell.weight.data.normal_(0.0, 0.02)
def forward(self, x):
return self.cell(x)
def main():
#print(*torch.__config__.show().split("\n"), sep="\n")
torch.set_num_threads(1)
dim = 32
kernels = 3
seq = 100000
MyCell = MyConv(dim, dim, kernel_size=kernels, stride=1)
MyCell.eval()
inputs = []
iter = 1000
for i in range(iter):
inputs.append(torch.rand(1, dim, seq))
start = time.time() * 1000
for i in range(iter):
print(i)
y = MyCell(inputs[i])
#print(y)
end = time.time() * 1000
print('cost %d ms per iter\n' % ((end - start) / iter))
if __name__ == "__main__":
main()
Mkldnn 详细信息 (运行 "export MKLDNN_VERBOSE=1")
mkldnn_verbose,exec,reorder,jit:uni,undef,in:f32_nchw out:f32_nChw8c,num:1,1x32x1x107718,2.18091
mkldnn_verbose,exec,reorder,jit:uni,undef,in:f32_oihw out:f32_OIhw8i8o,num:1,32x32x1x1,0.00195312
mkldnn_verbose,exec,convolution,jit_1x1:avx2,forward_training,fsrc:nChw8c fwei:OIhw8i8o fbia:x fdst:nChw8c,alg:convolution_direct,mb1_ic32oc32_ih1oh1kh1sh1dh0ph0_iw107718ow107718kw1sw1dw0pw0,3.87793
mkldnn_verbose,exec,reorder,jit:uni,undef,in:f32_nChw8c out:f32_nchw,num:1,1x32x1x107718,4.69116
非常感谢!
更多的线程并不意味着更快的速度。如果你有 4 个核心,你不能比 1 个核心的 4 倍更快。
你应该做的是在 single-thread 执行时调整你的代码以获得最大性能(关闭编译器优化),然后在你完成之后,打开编译器的优化器并使代码 multi-threaded,线程数不超过内核数。
来源:Multithreading - How to use CPU as much as possible?
我正在尝试使用 mkl-dnn 后端的 pytorch 模型。但是我遇到了一个问题,即多线程性能比预期的要慢,在小型转换上运行。请看这个 table。 mkl-dnn performace table
运行big conv,与单线程相比,8线程的性能明显更快。但是跑small conv,速度和8线程和单线程没有太大区别。
所以我的问题是: 1.为什么8个线程没有明显快于1个小conv的线程? 2. 如何提高8线程在small conv上的性能?
我的代码在这里
import time
import torch
import torch.nn as nn
from torch.nn.utils import weight_norm
class MyConv(nn.Module):
def __init__(self, *args, **kwargs):
super().__init__()
self.cell = nn.Conv1d(*args, **kwargs)
self.cell.weight.data.normal_(0.0, 0.02)
def forward(self, x):
return self.cell(x)
def main():
#print(*torch.__config__.show().split("\n"), sep="\n")
torch.set_num_threads(1)
dim = 32
kernels = 3
seq = 100000
MyCell = MyConv(dim, dim, kernel_size=kernels, stride=1)
MyCell.eval()
inputs = []
iter = 1000
for i in range(iter):
inputs.append(torch.rand(1, dim, seq))
start = time.time() * 1000
for i in range(iter):
print(i)
y = MyCell(inputs[i])
#print(y)
end = time.time() * 1000
print('cost %d ms per iter\n' % ((end - start) / iter))
if __name__ == "__main__":
main()
Mkldnn 详细信息 (运行 "export MKLDNN_VERBOSE=1")
mkldnn_verbose,exec,reorder,jit:uni,undef,in:f32_nchw out:f32_nChw8c,num:1,1x32x1x107718,2.18091
mkldnn_verbose,exec,reorder,jit:uni,undef,in:f32_oihw out:f32_OIhw8i8o,num:1,32x32x1x1,0.00195312
mkldnn_verbose,exec,convolution,jit_1x1:avx2,forward_training,fsrc:nChw8c fwei:OIhw8i8o fbia:x fdst:nChw8c,alg:convolution_direct,mb1_ic32oc32_ih1oh1kh1sh1dh0ph0_iw107718ow107718kw1sw1dw0pw0,3.87793
mkldnn_verbose,exec,reorder,jit:uni,undef,in:f32_nChw8c out:f32_nchw,num:1,1x32x1x107718,4.69116
非常感谢!
更多的线程并不意味着更快的速度。如果你有 4 个核心,你不能比 1 个核心的 4 倍更快。
你应该做的是在 single-thread 执行时调整你的代码以获得最大性能(关闭编译器优化),然后在你完成之后,打开编译器的优化器并使代码 multi-threaded,线程数不超过内核数。
来源:Multithreading - How to use CPU as much as possible?