Изучаю интересу ради работу сопроцессора.
И вот, напоролся на неожиданный результат.
#include "stdafx.h"
#include <conio.h>
#include <ctime>
#include <thread>
#define MAX_I 4000000
unsigned __int32 rezult[64];
std::thread* thr[8];
void StartPR(int str)
{
int i = MAX_I;
int x = str;
__asm {
mov eax, MAX_I
xor ebx, ebx
xor ecx, ecx
xor edx, edx
circle:
dec eax
mov i, eax
add ebx, i
add ecx, i
add edx, i
cmp eax, 0
jnz circle
mov eax, x
mov esi, eax
mov [rezult + esi], eax
add esi, 4
mov [rezult + esi], ebx
add esi, 4
mov [rezult + esi], ecx
add esi, 4
mov [rezult + esi], edx
}
}
void StartMMX(int str)
{
int i = MAX_I;
int x = str;
_asm {
mov eax, MAX_I
fldz
xor ebx, ebx
fldz
xor ecx, ecx
circle2:
dec eax
mov i, eax
add ecx, i
add ebx, i
fincstp
fld i
fadd st(1), st(0)
fadd st(2), st(0)
cmp eax, 0
jnz circle2
mov eax, x
mov esi, eax
mov dword ptr[rezult + esi], ebx
add esi, 4
fstp [rezult + esi]
add esi, 4
mov dword ptr[rezult + esi], ecx
add esi, 4
fstp [rezult + esi]
}
}
void stardThreads(int numOfThread)
{
printf("threads: %i", numOfThread);
int i = 0;
clock_t strt = clock();
for (int i = 1; i < numOfThread; i++)
{
thr[i] = new std::thread(StartPR, i * 32);
}
StartPR(0);
clock_t strt2 = clock();
clock_t bk1 = strt2 - strt;
i = 16;
for (int i = 1; i < numOfThread; i++)
{
thr[i] = new std::thread(StartMMX, i * 32 + 16);
}
StartMMX(i);
clock_t bk2 = clock() - strt2;
printf("time block1:%i, block2:%i, tics per second:%i\n", (__int32)bk1, (__int32)bk2, CLOCKS_PER_SEC);
//for (int i = 0; i < numOfThread * 8; i++)
//printf("rezult[%i] = %u \n", i, rezult[i]);
}
int _tmain(int argc, _TCHAR* argv[])
{
for (int i = 1; i < 9; i++)
stardThreads(i);
_getch();
return 0;
}
результат
threads: 1time block1:16, block2:5765, tics per second:1000
threads: 2time block1:22, block2:5653, tics per second:1000
threads: 3time block1:12, block2:3130, tics per second:1000
threads: 4time block1:17, block2:2430, tics per second:1000
threads: 5time block1:23, block2:3026, tics per second:1000
threads: 6time block1:14, block2:3401, tics per second:1000
threads: 7time block1:29, block2:3814, tics per second:1000
threads: 8time block1:21, block2:5198, tics per second:1000
блок StartMMX выполняется в тысячу раз медленнее блока StartPR. Причем, дело в командах сопроца. Если я их отключаю, моментально быстродействие сравнивается.
Кто подскажет, что я делаю не так?
Upd.
Поставил в количестве потоков цифры сперва 1, потом 4, и в конец офгел: в первом случае время неизменно и равно 6сек. Во втором - плавно опускается до 2сек и дальше остается таким. Как это в принципе возможно?