| 赞 | 87 |
| VIP | |
| 好人卡 | |
| 积分 | 136 |
| 经验 | |
| 最后登录 | 2021-1-24 |
| 在线时间 | 2753 小时 |
- 梦石
- 0
- 星屑
- 13562
- 在线时间
- 2753 小时
- 注册时间
- 2014-10-4
- 回帖
- 705

|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有账号?注册会员
×
本帖最后由 SixRC 于 2020-2-5 21:54 编辑
最近发现当任务量很小时 相对调用开销有点大
这时建议直接注册ruby方法
这东西对偶尔写汇编的来讲挺好用的
用途大概是提高某些部分效率 方便随时汇编上
模块名 ExtraFunc 下面功能
ExtraFunc.parse(code)
把汇编转换为对应机器码
输入字符串 返回字符串
可用标签来跳转
这个东西 99.9999% 基于 asmjit和asmtk 躺的好舒服
ExtraFunc.run(code, *args)
code是上一步返回的机器码 或者别的方式产生的 总之类型是字符串
args是参数 类型是整数 数量不限
传入的第一个参数是 [esp + 4] 依次类推
需要自己平堆栈 传几个参 最后反正 ret n*4
只有这个是自己写的 感觉好偷懒
ExtraFunc.tbb_for(ss,ee,st,func,*args)
tbb parallel_for
ss是for的开始值 ee是结束值 st是step
func和args同run
但是不同的是 传入给func的多了一个值 就是for给的
参数顺序是 i, arg1, arg2, ...
i就是 ss, ss + st, ss + 2st, ... 到 ee(不含)
这个就是多线程方法中的一个 别的我没写 我一般就用这个
ExtraFunc.tbb_allocate(size)
ExtraFunc.tbb_deallocate(pointer)
分别是申请内存和释放内存 用于多线程提高效率 或平常用
虽然写了这个方法 其实多线程用不到的
用的时候肯定是用dll的导出方法
因为机器码里不好调用ruby方法啊..
所以这个方法就平时申请内存用好了
别的功能我没写 反正基本是基于tbb的 要什么自己加什么
工程和源码
MTASM.zip
(1.35 MB, 下载次数: 43054)
工程里有一个小范例
这里也附一下 使用基本上都在里面了 吧
范例是图片反色的三种方法 :原版 汇编 及多线程+汇编 的比较
虽然原版限制太多 比方 color 的储存是浮点数 没p用 浪费效率
感觉比的很不公平 所以效率差是千倍的
别的范例我也不知道写啥 算了 反正百倍效率差基本是有的
这个例子多线程的作用感觉并不明显 (4核心约一倍提升)
因为核心循环代码量很少 速度很快
假如每个线程任务量大一点 多线程速度就体现出来了
[fold]
[pre lang="ruby"]w = 600
h = 600
a=Bitmap.new(w,h)
a.fill_rect(0,0,w,h,Color.new(0,255,255))
def reverse(a)
for i in 0...a.width
for j in 0...a.height
c = a.get_pixel(i,j)
c.red = 255 - c.red
c.green = 255 - c.green
c.blue = 255 - c.blue
a.set_pixel(i,j,c)
end
end
end
# pass addr,pixels
code = %Q{
mov esi,[esp+4]
mov ecx,[esp+8]
mov eax,0xffffff
again:
xor [esi],eax
add esi,4
dec ecx
jne again
ret 8
}
$asm = ExtraFunc.parse code
def reverse_asm(a)
ExtraFunc.run($asm,a.addr,a.width*a.height)
end
def reverse_mtasm(a)
ExtraFunc.tbb_for(a.addr,a.addr+a.width*a.height*4,a.width*4,$asm,a.width)
end
# ori
t=Time.now
1.times{reverse(a)}
t1 = Time.now - t
# asm
t=Time.now
1000.times{reverse_asm(a)}
t2 = Time.now - t
# multithreading asm
t=Time.now
1000.times{reverse_mtasm(a)}
t3 = Time.now - t
###
fac = 1/t3
t1 *= fac*1000
t2 *= fac
p t1,t2,1
s=Sprite.new
s.bitmap = a
loop{Graphics.update}[/pre]
[/fold]
下面这个是AVX版本的 范例里没带 刚写的
我的电脑上 AVX+多线程速度等于AVX单线程
原因似乎达到是内存读写/缓存 上限了
然后和原版差达到万倍
[fold]
[pre lang="ruby"]w = 600
h = 600
a=Bitmap.new(w,h)
a.fill_rect(0,0,w,h,Color.new(0,255,255))
def reverse(a)
for i in 0...a.width
for j in 0...a.height
c = a.get_pixel(i,j)
c.red = 255 - c.red
c.green = 255 - c.green
c.blue = 255 - c.blue
a.set_pixel(i,j,c)
end
end
end
mask = [0xFFFFFF].pack("l")*8
# pass addr,pixels
code = %Q{
mov esi,[esp+4]
mov ecx,[esp+8]
vmovdqu ymm0,[#{[mask].pack("p").unpack("l")[0]}]
sub ecx,8
jl ggg ; too small
again:
vpxor ymm1,ymm0,[esi]
vmovdqu [esi],ymm1
add esi,32
sub ecx,8
jg again
je ggg
lea esi,[esi + ecx * 4]
vmovdqu ymm1,[esi]
vpxor ymm1,ymm0,ymm1
vmovdqu [esi],ymm1
ggg:
ret 8
}
$asm = ExtraFunc.parse code
def reverse_asm(a)
ExtraFunc.run($asm,a.addr,a.width*a.height)
end
def reverse_mtasm(a)
ExtraFunc.tbb_for(a.addr,a.addr+a.width*a.height*4,a.width*4,$asm,a.width)
end
# ori
t=Time.now
1.times{reverse(a)}
t1 = Time.now - t
# asm
t=Time.now
4000.times{reverse_asm(a)}
t2 = Time.now - t
# multithreading asm
t=Time.now
4000.times{reverse_mtasm(a)}
t3 = Time.now - t
p t3
###
fac = 1/t3
t1 *= fac*4000
t2 *= fac
p t1,t2,1
s=Sprite.new
s.bitmap = a
loop{Graphics.update}[/pre]
[/fold] |
|