大数运算之内存操作篇

yaos 2004-07-24 11:53:36
// memfunc.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

unsigned long a[1048576];
unsigned long b[1048576];

//清零
void AsmMemZero(unsigned long * p, unsigned long t)
{
__asm
{
mov eax, dword ptr [p]
mov ecx, t
mov ebx, ecx
shr ebx, 3
mov edx, ebx
shl ebx, 3
sub ebx, ecx
cmp ebx, 0
jnz AsmMemZero0
mov ecx, edx
pxor mm0, mm0
movq mm2, mm0
pxor mm1, mm1
movq mm3, mm1
AsmMemZero1:
movntq [eax], mm0
movntq [eax + 8], mm1
movntq [eax + 16], mm2
movntq [eax + 24], mm3
add eax, 32
loop AsmMemZero1
AsmMemZero0:
cmp ebx, 0
je AsmMemZero3
mov ecx, ebx
mov ebx, 0
AsmMemZero2:
mov [eax], ebx
add eax, 4
loop AsmMemZero2
AsmMemZero3:
sfence
emms
}
}

void AsmMemCopy(unsigned long * pS, unsigned long * pD, unsigned long t)
{
}

int _tmain(int argc, _TCHAR* argv[])
{
unsigned long i;
for (i = 0; i < 1048576; i ++)
{
a[i] = 0xFFFFFFFF;
b[i] = 0xFFFFFFFF;
}

for (i = 0; i < 10000; i ++)
AsmMemZero(a, 1048576);

for (i = 0; i < 100000; i ++)
AsmMemCopy(a, b, 1048576);

return 0;
}


P4 XEON * 2 1024 MB内存 win2000 AS (SP4 +)
清零过程
for (i = 0; i < 10000; i ++)
AsmMemZero(a, 1048576);
23秒 大约1739 MB / s
...全文
159 12 打赏 收藏 转发到动态 举报
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
yaos 2004-07-26
  • 打赏
  • 举报
回复
:)

感觉这个内存速度比一般机器的DDR400双通道还好
heidongstar 2004-07-26
  • 打赏
  • 举报
回复
好夸张的内存,不过带宽低点,还是DDRII的NB。
yaos 2004-07-25
  • 打赏
  • 举报
回复
顺便说一下
这个机器是1024 MB ECC PC2100 DDR 双通道结构
理论带宽 4.2 GB / s
yaos 2004-07-25
  • 打赏
  • 举报
回复
void AsmMemZero(unsigned long * p, unsigned long t)
{
__asm
{
mov ecx, t
cmp ecx, 0
je AsmMemZero3
mov eax, dword ptr [p]
mov ebx, 0
test eax, 15 //不是16字节对齐的执行下面的语句
je AsmMemZero4
mov edx, eax
shr edx, 4
shl edx, 4
cmp edx, eax
je AsmMemZero4
add edx, 16
sub edx, eax
shr edx, 2
sub ecx, edx
AsmMemZero7:
mov [eax], ebx
add eax, 4
sub edx, 1
jne AsmMemZero7
cmp ecx, 0
je AsmMemZero3
AsmMemZero4:
mov ebx, ecx
shr ebx, 2
mov edx, ebx
shl ebx, 2
cmp ebx, 0 //是否不足16字节
je AsmMemZero6
sub ecx, ebx
mov ebx, ecx //保留末尾的不足16字节的部分
mov ecx, edx //循环的次数
pxor xmm0, xmm0
AsmMemZero1:
movntdq [eax], xmm0
add eax, 16
loop AsmMemZero1
AsmMemZero0:
cmp ebx, 0
je AsmMemZero3
mov ecx, ebx
AsmMemZero6:
mov ebx, 0
AsmMemZero2:
mov [eax], ebx
add eax, 4
loop AsmMemZero2
AsmMemZero3:
sfence
emms
}
}

修改的清零函数
测试语句
for (i = 0; i < 10000; i ++)
AsmMemZero(a + 3, 1048576);

配置同题目,CPU占用25%
时间 23 s,速度大约1.7 GB / s
普通的机器测试请大家自己做

可惜是服务器,不能调节到接近实时,哎
家里的机器测试以后做吧 :)
yaos 2004-07-24
  • 打赏
  • 举报
回复
没法子了,要被迫使用XMM传送16字节数据了

但愿这个不出现兼容性和速度的明显差异

CPU是4个,因为支持HT,嘿嘿,有点麻烦
shines77 2004-07-24
  • 打赏
  • 举报
回复
MOVNTQ--Move Quadword Non-Temporal
http://folk.uio.no/botnen/intel/vt/reference/vc198.htm

前面那个问题可能跟non-temporal hint特别的写入方式有关吧,不经过缓存
也许也跟CPU的个数有关
yaos 2004-07-24
  • 打赏
  • 举报
回复
上边的函数大约1.6 GB / s
配置同题目,另外CPU占用率25%,没测试实时的情况
yaos 2004-07-24
  • 打赏
  • 举报
回复
void AsmMemZero(unsigned long * p, unsigned long t)
{
__asm
{
mov ecx, t
cmp ecx, 0
je AsmMemZero3
mov eax, dword ptr [p]
mov ebx, 0
test eax, 7 //不是8字节对齐的执行下面的语句
je AsmMemZero4
mov [eax], ebx
add eax, 4
dec ecx
je AsmMemZero3
AsmMemZero4:
mov ebx, ecx
shr ebx, 3
mov edx, ebx
shl ebx, 3
cmp ebx, 0 //是否不足32字节
je AsmMemZero6
sub ecx, ebx
mov ebx, ecx //保留末尾的不足32字节的部分
mov ecx, edx //循环的次数
pxor mm0, mm0
movq mm2, mm0
pxor mm1, mm1
movq mm3, mm1
AsmMemZero1:
movntq [eax], mm0
movntq [eax + 8], mm1
movntq [eax + 16], mm2
movntq [eax + 24], mm3
add eax, 32
loop AsmMemZero1
AsmMemZero0:
cmp ebx, 0
je AsmMemZero3
mov ecx, ebx
AsmMemZero6:
mov ebx, 0
AsmMemZero2:
mov [eax], ebx
add eax, 4
loop AsmMemZero2
AsmMemZero3:
sfence
emms
}
}

最终的应付所有情况的函数形式 :)
只需要修改核心的几句就能变换为其他形式
kbsoft 2004-07-24
  • 打赏
  • 举报
回复
佩服,高手就是高手!
yaos 2004-07-24
  • 打赏
  • 举报
回复
似乎与机器芯片组有关系?

家里的机器sis的芯片组
题目机器intel的
yaos 2004-07-24
  • 打赏
  • 举报
回复
题目函数改movntq为movq

53秒

机器配置同题目
yaos 2004-07-24
  • 打赏
  • 举报
回复
void AsmMemZero(unsigned long * p, unsigned long t)
{
if (t == 0)
return;
__asm
{
mov eax, dword ptr [p]
mov edx, t
mov ebx, edx
shr ebx, 2
mov ecx, ebx
shl ebx, 2
sub edx, ebx
cmp ecx, 0
jz asmmemzero1
pxor mm0, mm0
asmmemzero0:
movq [eax], mm0
movq [eax+8], mm0
add eax, 16
loop asmmemzero0
asmmemzero1:
cmp edx, 0
jz asmmemzero3
mov ecx, edx
mov ebx ,0
asmmemzero2:
mov dword ptr [eax], ebx
add eax, 4
loop asmmemzero2
asmmemzero3:
emms
}
}

54秒,配置同上

在P4 2.0 256DDR上的测试正好相反,这个函数速度快,题目上的函数却很慢 :(

33,010

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧