|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2007-8-2 17:03
|
显示全部楼层
假如用BC和VC,倒序算法可以这样优化:
- void __declspec(naked) mySplit_A(double *pData, int nCount){ // for intel single and AMD
- asm{
- push ebp
- mov ebp,esp
- add esp,-12
- push ebx
- push esi
- xor ecx,ecx
- mov eax,dword ptr [ebp+12]
- add eax,eax
- dec eax
- mov dword ptr [ebp-4],eax
- mov edx,dword ptr [ebp+8]
- add edx,8
- mov dword ptr [ebp-8],edx
- mov edx,ecx
- cmp ecx,dword ptr [ebp-4]
- jge short my@16
- // ; EDX = j, ECX = i, EBX = @temp3
- my@15:
- cmp ecx,edx
- jge short my@17
- mov esi, dword ptr [ebp+8] //pData
- mov eax, dword ptr [esi + 8*edx] // eax = pData[j]
- mov ebx, dword ptr [esi + 8*ecx] // ebx = pData[i]
- mov dword ptr [esi + 8*ecx], eax // pData[i] = eax
- mov dword ptr [esi + 8*edx], ebx // pData[j] = ebx
- add esi, 4
- mov eax, dword ptr [esi + 8*edx] // eax = pData[j]
- mov ebx, dword ptr [esi + 8*ecx] // ebx = pData[i]
- mov dword ptr [esi + 8*ecx], eax // pData[i] = eax
- mov dword ptr [esi + 8*edx], ebx // pData[j] = ebx
- mov esi, dword ptr [ebp-8] //pDataI
- mov eax, dword ptr [esi + 8*edx] // eax = pData[j]
- mov ebx, dword ptr [esi + 8*ecx] // ebx = pData[i]
- mov dword ptr [esi + 8*ecx], eax // pData[i] = eax
- mov dword ptr [esi + 8*edx], ebx // pData[j] = ebx
- add esi, 4
- mov eax, dword ptr [esi + 8*edx] // eax = pData[j]
- mov ebx, dword ptr [esi + 8*ecx] // ebx = pData[i]
- mov dword ptr [esi + 8*ecx], eax // pData[i] = eax
- mov dword ptr [esi + 8*edx], ebx // pData[j] = ebx
- my@17:
- mov eax,dword ptr [ebp+12]
- jmp short my@19
- // ; EAX = m, EDX = j, ECX = i, EBX = @temp3
- my@18:
- sub edx,eax
- sar eax,1
- my@19:
- cmp eax,2
- jl short my@20
- cmp eax,edx
- jle short my@18
- my@20:
- add edx,eax
- add ecx,2
- // add dword ptr [ebp-12],16
- // add ebx,16
- cmp ecx,dword ptr [ebp-4]
- jl short my@15
- //?live16388@224: ;
- my@16:
- //@22:
- pop esi
- pop ebx
- mov esp, ebp
- pop ebp
- ret
- }
- //---------------------------------------------------------------------------
- void __declspec(naked) mySplit_A2(double *pData, int nCount){// for intel duro core & AMD
- asm{
- push ebp
- mov ebp,esp
- add esp,-12
- push ebx
- push esi
- xor ecx,ecx
- mov eax,dword ptr [ebp+12]
- add eax,eax
- dec eax
- mov dword ptr [ebp-4],eax
- mov edx,dword ptr [ebp+8]
- add edx,8
- mov dword ptr [ebp-8],edx
- mov edx,ecx
- cmp ecx,dword ptr [ebp-4]
- jge short my@216
- // ; EDX = j, ECX = i, EBX = @temp3
- my@215:
- cmp ecx,edx
- jge short my@217
- mov esi, dword ptr [ebp+8] //pData
- fwait
- fld [esi + 8*edx] // st0 = pData[j]
- fld [esi + 8*ecx] // st0 = pData[i]; st1 = pData[j]
- fstp [esi + 8*edx] // st0 -> pData[j] ; st0 = old pData[j]
- fstp [esi + 8*ecx]
- mov esi, dword ptr [ebp-8] //pDataI
- fld [esi + 8*edx] // st0 = pData[j]
- fld [esi + 8*ecx] // st0 = pData[i]; st1 = pData[j]
- fstp [esi + 8*edx] // st0 -> pData[j] ; st0 = old pData[j]
- fstp [esi + 8*ecx]
- my@217:
- mov eax,dword ptr [ebp+12]
- jmp short my@219
- // ; EAX = m, EDX = j, ECX = i, EBX = @temp3
- my@218:
- sub edx,eax
- sar eax,1
- my@219:
- cmp eax,2
- jl short my@220
- cmp eax,edx
- jle short my@218
- my@220:
- add edx,eax
- add ecx,2
- // add dword ptr [ebp-12],16
- // add ebx,16
- cmp ecx,dword ptr [ebp-4]
- jl short my@215
- //?live16388@224: ;
- my@216:
- //@22:
- pop esi
- pop ebx
- mov esp, ebp
- pop ebp
- ret
- }
- }
- //---------------------------------------------------------------------------
复制代码
不过,假如单线程时,或者,假如对很大的数据块进行操作时,即使你的cpu是双核的,
你也要在调用汇编倒序函数之前 和 mov之间,插入适当的 fwait 指令和 memory lock函数。
要不然,还是让VC 和 BC的编译器自己优化,不要用汇编。
因为windows xp和vesta里面,对大的连续内存管理的很抠。
加上matlab自己没有动态内存管理,你不加入 lock & wait or fwait,一旦你的过程运行超过一个时间段,就会被windows的内存管理接管,从而花费很多时间,在无端的总线等待上,尤其是执行到mov指令时,你的指令也许就一个时钟周期,你的wait可以最差到4个周期。
所以,我们提倡用多线程,然后,将自己的权限提高,这样就可以得到更多的cpu资源了。
这里虽然贴了优化,但是不提倡用。
[ 本帖最后由 recbio 于 2007-8-2 18:09 编辑 ] |
|