[准备/原创]:亲身体验多核/超线程

背包问题,我写了两个版本的算法程序,bag 和 bag-mt 其中后者是多线程版本,其
使用 4 线程分段计算验证,编写语言是 ASM ,详情请向下观赏:

概述:

1  我的程序对内存访问也是比较频繁密集的,还有就是 xeon 是负载服务器,上面
    还有N个后台进程在驻留,可能可这个也有关系。

2  为了加速,我比较多的使用局部变量,省去临界区,互斥事件的耗时。最后汇总。

源码:

bag:

.386
.model flat,stdcall
option casemap:none

include c:/masm32/include/windows.inc
include c:/masm32/include/user32.inc
includelib c:/masm32/lib/user32.lib
include c:/masm32/include/kernel32.inc
includelib c:/masm32/lib/kernel32.lib

CDim    equ      28

.const
wetdb220,56,79,135,21,5,175,90,11,153;KG
db25,68,123,35,8,94,207,2,67,159
db78,34,43,12,167,231,12,54,98,32
db65,146,57,234,65,93,56,243,8,56
valdb60,100,45,26,90,10,57,240,136,230;$
db78,34,7,23,89,250,129,94,45,24
db56,89,34,124,78,5,45,234,89,32
db34,72,50,147,180,210,45,18,69,94
limwetdd400;Limit Wet
twodd2
ftdb'TTs == %d ,MaxWet == %d , MaxVal == %d ,TakeTime == %d',0
cpdb'Windows XP',0

.data?
MaxValdd?
MaxWetdd?
nbndd?
tmptimedd?
TTsdd?
bufdb256dup(?)

.code
;~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
EnumCtproc
localTmpWet
locali

movnbn,1
movTmpWet,0

.whilenbn<=0fffffffh;2^CDim - 1
movi,0
xorebx,ebx
.whilei<CDim
moveax,i

btnbn,eax
.ifCARRY?
moval,wet[eax]
andeax,0ffh
addebx,eax
.endif
inci
.endw
.ifebx > limwet
jmpa0
.endif
movTmpWet,ebx
movi,0
xorebx,ebx
.whilei<CDim
moveax,i

btnbn,eax
.ifCARRY?
moval,val[eax]
andeax,0ffh
addebx,eax
.endif
inci
.endw
.ifebx > MaxVal
movMaxVal,ebx
movebx,TmpWet
movMaxWet,ebx
.endif
a0:
incTTs
incnbn
.endw

ret

EnumCtendp
;~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
start:

movTTs,0
movMaxVal,0
movMaxWet,0
invokeGetTickCount
movtmptime,eax

invokeEnumCt

invokeGetTickCount
subeax,tmptime

invokewsprintf,addr buf,addr ft,TTs,MaxWet,MaxVal,eax
invokeMessageBox,NULL,addr buf,addr cp,MB_OK

invokeExitProcess,NULL
;~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
endstart

bag-mt:

.386
.model flat,stdcall
option casemap:none

includec:/masm32/include/windows.inc
includec:/masm32/include/user32.inc
includelibc:/masm32/lib/user32.lib
includec:/masm32/include/kernel32.inc
includelibc:/masm32/lib/kernel32.lib

CDimequ28

cststruct
sfdd?
efdd?
ttsdd?
mwdd?
mvdd?
cstends

.const
wetdb220,56,79,135,21,5,175,90,11,153;KG
db25,68,123,35,8,94,207,2,67,159
db78,34,43,12,167,231,12,54,98,32
db65,146,57,234,65,93,56,243,8,56
valdb60,100,45,26,90,10,57,240,136,230;$
db78,34,7,23,89,250,129,94,45,24
db56,89,34,124,78,5,45,234,89,32
db34,72,50,147,180,210,45,18,69,94
limwetdd400;Limit Wet
ft0db'TTs == %d ,MaxWet == %d , MaxVal == %d ',0
ft1db'Total TakeTime == %d',0
cpdb'Windows XP',0

.data
cst0cst<1,4000000h,0,0,0>
cst1cst<4000001h,8000000h,0,0,0>
cst2cst<8000001h,0c000000h,0,0,0>
cst3cst<0c000001h,0fffffffh,0,0,0>

.data?
tmptimedd?
ht0dd?
ht1dd?
ht2dd?
ht3dd?
bufdb256dup(?)

.code
;~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
EnumCtproclpcst
localTmpWet
localTmpnbn
locali

movedi,lpcst
assumeedi:ptr cst

push [edi].sf
popTmpnbn
movTmpWet,0
movedx,[edi].ef

.whileTmpnbn<=edx;2^CDim - 1
movi,0
xorebx,ebx
.whilei<CDim
moveax,i

btTmpnbn,eax
.ifCARRY?
moval,wet[eax]
andeax,0ffh
addebx,eax
.endif
inci
.endw
.ifebx > limwet
jmpa0
.endif
movTmpWet,ebx
movi,0
xorebx,ebx
.whilei<CDim
moveax,i

btTmpnbn,eax
.ifCARRY?
moval,val[eax]
andeax,0ffh
addebx,eax
.endif
inci
.endw
.ifebx > [edi].mv
mov[edi].mv,ebx
movebx,TmpWet
mov[edi].mw,ebx
.endif
a0:
inc[edi].tts
incTmpnbn
.endw

ret

EnumCtendp
;~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
start:
invokeGetTickCount
movtmptime,eax

invokeCreateThread,NULL,0,addr EnumCt,addr cst0,/
NULL,NULL
movht0,eax
invokeCreateThread,NULL,0,addr EnumCt,addr cst1,/
NULL,NULL
movht1,eax
invokeCreateThread,NULL,0,addr EnumCt,addr cst2,/
NULL,NULL
movht2,eax
invokeCreateThread,NULL,0,addr EnumCt,addr cst3,/
NULL,NULL
movht3,eax
invokeWaitForMultipleObjects,4,addr ht0,TRUE,INFINITE

invokeGetTickCount
subeax,tmptime
movtmptime,eax

invokewsprintf,addr buf,addr ft0,cst0.tts,cst0.mw,cst0.mv
invokeMessageBox,NULL,addr buf,addr cp,MB_OK
invokewsprintf,addr buf,addr ft0,cst1.tts,cst1.mw,cst1.mv
invokeMessageBox,NULL,addr buf,addr cp,MB_OK
invokewsprintf,addr buf,addr ft0,cst2.tts,cst2.mw,cst2.mv
invokeMessageBox,NULL,addr buf,addr cp,MB_OK
invokewsprintf,addr buf,addr ft0,cst3.tts,cst3.mw,cst3.mv
invokeMessageBox,NULL,addr buf,addr cp,MB_OK
invokewsprintf,addr buf,addr ft1,tmptime
invokeMessageBox,NULL,addr buf,addr cp,MB_OK


invokeExitProcess,NULL
;~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~
endstart

对于 bag-mt 略作说明:

a 采用的是 4 线程'并发'

b 使用了 对象等待 win32 API

以上代码均用 masm32v8.2 编译连接通过,其编译连接指令为:

ml /c /coff name.asm
link /subsystem:console name.obj

欢迎大家用编译连接后的 exe 作测试,并贴上测试结果,同时给出cpu类型
masm32 编译器请到:

www.masm32.com 或 www.aogosoft.com 下载,有问题请和我联系。

你可能感兴趣的:(多线程,windows,db2,null,include,tts)