Здравствуйте (и извините за мой плохой английский), из-за некоторых проблем с переносимостью мне нужно написать себе функцию копирования в память.Но моя лучшая попытка сделать это на 40-70% медленнее, чем стандартная memcpy для Visual Studio 2010.И я не знаю почему.Далее вы можете увидеть мой основной цикл копирования, который копирует все 128-байтовые куски данных (весь другой код из функции ограничен в количестве операций и может быть принят как O (1))
MOVDQA XMM0,DQWORD PTR DS:[ESI]
MOVDQA XMM1,DQWORD PTR DS:[ESI+10]
MOVDQA XMM2,DQWORD PTR DS:[ESI+20]
MOVDQA XMM3,DQWORD PTR DS:[ESI+30]
MOVDQA DQWORD PTR DS:[EDI],XMM0
MOVDQA DQWORD PTR DS:[EDI+10],XMM1
MOVDQA DQWORD PTR DS:[EDI+20],XMM2
MOVDQA DQWORD PTR DS:[EDI+30],XMM3
MOVDQA XMM4,DQWORD PTR DS:[ESI+40]
MOVDQA XMM5,DQWORD PTR DS:[ESI+50]
MOVDQA XMM6,DQWORD PTR DS:[ESI+60]
MOVDQA XMM7,DQWORD PTR DS:[ESI+70]
MOVDQA DQWORD PTR DS:[EDI+40],XMM4
MOVDQA DQWORD PTR DS:[EDI+50],XMM5
MOVDQA DQWORD PTR DS:[EDI+60],XMM6
MOVDQA DQWORD PTR DS:[EDI+70],XMM7
LEA ESI,[ESI+80]
LEA EDI,[EDI+80]
DEC ECX
JNE SHORT 002410B9
И далеея нашел в стандартном memcpy
MOVDQA XMM0,DQWORD PTR DS:[ESI]
MOVDQA XMM1,DQWORD PTR DS:[ESI+10]
MOVDQA XMM2,DQWORD PTR DS:[ESI+20]
MOVDQA XMM3,DQWORD PTR DS:[ESI+30]
MOVDQA DQWORD PTR DS:[EDI],XMM0
MOVDQA DQWORD PTR DS:[EDI+10],XMM1
MOVDQA DQWORD PTR DS:[EDI+20],XMM2
MOVDQA DQWORD PTR DS:[EDI+30],XMM3
MOVDQA XMM4,DQWORD PTR DS:[ESI+40]
MOVDQA XMM5,DQWORD PTR DS:[ESI+50]
MOVDQA XMM6,DQWORD PTR DS:[ESI+60]
MOVDQA XMM7,DQWORD PTR DS:[ESI+70]
MOVDQA DQWORD PTR DS:[EDI+40],XMM4
MOVDQA DQWORD PTR DS:[EDI+50],XMM5
MOVDQA DQWORD PTR DS:[EDI+60],XMM6
MOVDQA DQWORD PTR DS:[EDI+70],XMM7
LEA ESI,[ESI+80]
LEA EDI,[EDI+80]
DEC EDX
JNE SHORT 6B150A72
Как вы можете видеть, этот цикл почти идентичен моему, но моя функция становится все медленнее и медленнее (по сравнению с std memcpy) с увеличением количества копируемых данных.
Может кто-нибудь ответить, где моя ошибка?
PS Это мой код из main ()
void main(void){
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
int* mas = new int[10000000];
for(int i = 0; i < 10000000; ++i)
mas[i] = i;
LARGE_INTEGER mmcpy = { 0 };
LARGE_INTEGER mmsse = { 0 };
for(int i = 0; i < 10000; ++i)
{
LARGE_INTEGER beforeMemcpy_sse, afterMemcpy_sse;
QueryPerformanceCounter(&beforeMemcpy_sse);
TestMemcpy_sse(mas, (char*)mas + 300000, 4400000);
QueryPerformanceCounter(&afterMemcpy_sse);
LARGE_INTEGER beforeMemcpy, afterMemcpy;
QueryPerformanceCounter(&beforeMemcpy);
memcpy(mas, (char*)mas + 300000, 4400000);
QueryPerformanceCounter(&afterMemcpy);
mmcpy.QuadPart += afterMemcpy.QuadPart - beforeMemcpy.QuadPart ;
mmsse.QuadPart += afterMemcpy_sse.QuadPart - beforeMemcpy_sse.QuadPart;
}
delete[] mas;
/*printf("Memcpy Time: %f\n", (afterMemcpy.QuadPart - beforeMemcpy.QuadPart) / (float)freq.QuadPart);
printf("SSE Memcpy Time: %f\n\n", (afterMemcpy_sse.QuadPart - beforeMemcpy_sse.QuadPart) / (float)freq.QuadPart);*/
printf("Memcpy Time: %f\n", mmcpy.QuadPart / ((float)freq.QuadPart * 10000));
printf("SSE Memcpy Time: %f\n\n", mmsse.QuadPart / ((float)freq.QuadPart * 10000));
system("pause");
}