同步指令分析
为避免数据的内存地址存在踩踏的问题, 系统在算子编译时自动插入同步指令,但冗余的同步指令会降低算子的性能。TIK提供了分级同步功能,可以设置某个代码段在算子编译时不自动插入同步指令,但此时开发人员需要确保内存地址不存在踩踏问题。
设置编译时不自动插入同步指令的方法是为对应代码块设置scope,并设置“disable_sync”标识为“True”:
with tik_instance.new_stmt_scope(disable_sync=True)
new_stmt_scope范围内空间代表一个新作用域,如果可以确保此作用域内的API之间不存在数据依赖,则可以设置“disable_sync”标识为“True”,则算子编译时不会插入同步指令,算子性能会更高,如下所示:
tik_instance = tik.Tik() dtype = "float16" shape = (2, 128) src_gm = tik_instance.Tensor(dtype, shape, name="src_gm", scope=tik.scope_gm) src_ub = tik_instance.Tensor(dtype, shape, name="src_ub", scope=tik.scope_ubuf) dst_gm = tik_instance.Tensor(dtype, shape, name="dst_gm", scope=tik.scope_gm) dst_ub = tik_instance.Tensor(dtype, shape, name="dst_ub", scope=tik.scope_ubuf) a = tik_instance.InputScalar(dtype="int32", name="a") b = tik_instance.InputScalar(dtype="int32", name="b") tik_instance.data_move(src_ub, src_gm, 0, 1, 16, 0, 0) # 如果配置disable_sync为False,data_move的offset为Scalar,系统无法判断两个data_move之间数据地址是否有重叠,系统就会自动插入同步指令。 # 如果知道a和b的具体值,比如输入a为0,b为1,那么两个data_move之间没有数据依赖,就可以配置disable_sync为True,不插入同步指令,取消搬运指令间的同步等待,可以提升性能。 with tik_instance.new_stmt_scope(disable_sync=True): tik_instance.data_move(dst_ub[a*128:], src_ub[a*128:], 0, 1, 8, 0, 0) tik_instance.data_move(dst_ub[b*128:], src_ub[b*128:], 0, 1, 8, 0, 0) tik_instance.data_move(dst_gm, dst_ub, 0, 1, 16, 0, 0) tik_instance.BuildCCE(kernel_name="sample", inputs=[src_gm, a, b], outputs=[dst_gm])
父主题: TIK性能优化