powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Ну очень быстрый Move() для x86/x64
13 сообщений из 38, страница 2 из 2
Ну очень быстрый Move() для x86/x64
    #38779617
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
SOFT FOR YOUНо порой не получается обойтись без Move. Это и операции со строками, и динамическими массивами, и в моём случае запись/чтение данных в "стрим"

Чтобы Move имело смысл как-то существенно ускорять, копировать нужно именно большие объёмы,
на малых объёмах разницы, видимой глазу, не будет, разве что эффект плацебо.
...
Рейтинг: 0 / 0
Ну очень быстрый Move() для x86/x64
    #38779646
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
defecatorЧтобы Move имело смысл как-то существенно ускорять, копировать нужно именно большие объёмы,
на малых объёмах разницы, видимой глазу, не будет, разве что эффект плацебо.
Чтобы Move имело смысл ускорять - нужно чтобы Move использовался часто. Это мой случай
И наверняка не только мой :)
...
Рейтинг: 0 / 0
Ну очень быстрый Move() для x86/x64
    #38780589
TVoid
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
SOFT FOR YOU,
Src: https://yadi.sk/d/7ayPhNkoc6fEF
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
var
 mSize     :Cardinal;
 mOffsetS  :Cardinal;
 mOffsetD  :Cardinal;
 tResult  :string;

procedure Test(aVoid:Pointer);
const 
 GB = UInt64(8)*1024*1024*1024;
var 
 i,n,t :NativeUInt;
 pS,pD :Pointer;
begin

 tResult := 'Error?!';

 pS := VirtualAlloc(nil,mSize,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE); // pS := GetMemory(mSize); 
 pD := VirtualAlloc(nil,mSize,MEM_COMMIT or MEM_RESERVE,PAGE_READWRITE); // pD := GetMemory(mSize); 

 if (pS <> nil) and (pD <> nil) then begin

  ZeroMemory(pS,mSize);
  ZeroMemory(pD,mSize);
 
  n := GB div mSize - 1;
  tResult := IntToStr( mSize div 1024) +'KB x ' +IntToStr((n+1) div 1024) +'Kn S+' +IntToStr(mOffsetS) +' D+' +IntToStr(mOffsetD) +' :';

  pS := PByte(pS) + mOffsetS;
  pD := PByte(pD) + mOffsetD;
  if (mOffsetS > mOffsetD) then Dec(mSize, mOffsetS) else Dec(mSize, mOffsetD);
  
  t := GetTickCount();
   for i := 0 to n do NonCollisionMove(pS^,pD^,mSize);
  tResult := tResult + #9'Na ' + IntToStr(GetTickCount() - t);

  t := GetTickCount();
   for i := 0 to n do Move(pS^,pD^,mSize);
  tResult := tResult + #9'Ma ' + IntToStr(GetTickCount() - t);

  t := GetTickCount();
   for i := 0 to n do NonCollisionMove(pS^,pD^,mSize);
  tResult := tResult + #9'Nb ' + IntToStr(GetTickCount() - t);

  t := GetTickCount();
   for i := 0 to n do Move(pS^,pD^,mSize);
  tResult := tResult + #9'Mb ' + IntToStr(GetTickCount() - t);

  t := GetTickCount();
   for i := 0 to n do  NonCollisionMove(pS^,pD^,mSize);
  tResult := tResult + #9'Nc ' + IntToStr(GetTickCount() - t);

 end;
 
 pS:=PByte(pS)-mOffsetS;
 pD:=PByte(pD)-mOffsetD;

 VirtualFree(pD,0,MEM_RELEASE); // FreeMemory(pS);
 VirtualFree(pS,0,MEM_RELEASE); // FreeMemory(pD); 
 
 PostMessage(Form1.Handle,WM_USER,0,0); 
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
 mSize := StrToIntDef(Edit1.Text,4); 
 mOffsetS := StrToIntDef(Edit2.Text,0);
 mOffsetD := StrToIntDef(Edit3.Text,0);   
 mSize:=mSize * 1024; 
 Button1.Enabled := False;
 CloseHandle(BeginThread(nil,0,@Test,nil,0,PCardinal(nil)^));
end;

procedure TForm1.WmUser(var Message: TMessage);
begin
 Memo1.Lines.Add(tResult);
 Button1.Enabled := True;                                  
end;



binXE4: https://yadi.sk/d/E3FCMpKLc6exQ
binXE7: https://yadi.sk/d/wqThCXNsc6esT

CPU E5-2670

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
///  Intel(R) Xeon(R) CPU E5-2670 0 @ 2.60GHz 

128KB x 64Kn S+0 D+1 :	Na 639	Ma 858	Nb 484	Mb 842	Nc 484
128KB x 64Kn S+0 D+1 :	Na 639	Ma 858	Nb 484	Mb 936	Nc 468
128KB x 64Kn S+1 D+0 :	Na 655	Ma 1482	Nb 468	Mb 1482	Nc 468
128KB x 64Kn S+1 D+0 :	Na 608	Ma 1482	Nb 468	Mb 1482	Nc 468
256KB x 32Kn S+0 D+1 :	Na 967	Ma 1108	Nb 795	Mb 1092	Nc 811
256KB x 32Kn S+0 D+1 :	Na 1014	Ma 1108	Nb 811	Mb 1107	Nc 796
512KB x 16Kn S+0 D+1 :	Na 998	Ma 1155	Nb 795	Mb 1108	Nc 796
512KB x 16Kn S+0 D+1 :	Na 983	Ma 1123	Nb 796	Mb 1107	Nc 812
512KB x 16Kn S+0 D+0 :	Na 858	Ma 1030	Nb 780	Mb 1045	Nc 780
1024KB x 8Kn S+0 D+1 :	Na 1139	Ma 1170	Nb 811	Mb 1107	Nc 812
1024KB x 8Kn S+0 D+1 :	Na 1014	Ma 1108	Nb 951	Mb 1108	Nc 827
2048KB x 4Kn S+0 D+1 :	Na 1045	Ma 1186	Nb 858	Mb 1185	Nc 858
2048KB x 4Kn S+0 D+0 :	Na 904	Ma 1139	Nb 812	Mb 1123	Nc 795
4096KB x 2Kn S+0 D+1 :	Na 1045	Ma 1170	Nb 874	Mb 1170	Nc 873 //
4096KB x 2Kn S+1 D+0 :	Na 1029	Ma 2044	Nb 827	Mb 2246	Nc 827 \\
2048KB x 4Kn S+1 D+0 :	Na 1014	Ma 2059	Nb 843	Mb 2044	Nc 842   //
1024KB x 8Kn S+1 D+0 :	Na 983	Ma 7114	Nb 795	Mb 6927	Nc 795 !!
1024KB x 8Kn S+1 D+0 :	Na 1107	Ma 6927	Nb 795	Mb 6958	Nc 811 !!
512KB x 16Kn S+1 D+0 :	Na 1030	Ma 1872	Nb 811	Mb 1888	Nc 795   \\
768KB x 10Kn S+1 D+0 :	Na 1061	Ma 1888	Nb 795	Mb 1857	Nc 795
1024KB x 8Kn S+1 D+0 :	Na 998	Ma 6927	Nb 795	Mb 6942	Nc 796 //
1024KB x 8Kn S+0 D+1 :	Na 998	Ma 1108	Nb 826	Mb 1108	Nc 827 \\
2048KB x 4Kn S+0 D+1 :	Na 1061	Ma 1186	Nb 873	Mb 1186	Nc 874
2048KB x 4Kn S+1 D+0 :	Na 1092	Ma 2044	Nb 826	Mb 2059	Nc 843
1024KB x 8Kn S+1 D+0 :	Na 967	Ma 6926	Nb 812	Mb 6926	Nc 811 //

4KB x 2048Kn S+0 D+0 :	Na 405	Ma 1045	Nb 266	Mb 873	Nc 265

8KB x 1024Kn S+0 D+0 :	Na 390	Ma 889	Nb 234	Mb 843	Nc 234
8KB x 1024Kn S+1 D+0 :	Na 452	Ma 952	Nb 328	Mb 936	Nc 312 +
8KB x 1024Kn S+0 D+1 :	Na 499	Ma 874	Nb 327	Mb 874	Nc 327 +
8KB x 1024Kn S+0 D+0 :	Na 422	Ma 936	Nb 234	Mb 842	Nc 234

1KB x 8192Kn S+0 D+0 :	Na 515	Ma 1045	Nb 359	Mb 1030	Nc 358
1KB x 8192Kn S+1 D+0 :	Na 577	Ma 1107	Nb 359	Mb 1077	Nc 358 +
1KB x 8192Kn S+0 D+1 :	Na 546	Ma 1232	Nb 344	Mb 1045	Nc 343

16KB x 512Kn S+1 D+0 :	Na 468	Ma 967	Nb 328	Mb 967	Nc 328
16KB x 512Kn S+0 D+1 :	Na 514	Ma 968	Nb 358	Mb 843	Nc 343 +
16KB x 512Kn S+0 D+0 :	Na 452	Ma 874	Nb 281	Mb 827	Nc 265

32KB x 256Kn S+0 D+0 :	Na 640	Ma 858	Nb 452	Mb 843	Nc 452
32KB x 256Kn S+1 D+0 :	Na 640	Ma 1466	Nb 468	Mb 1467	Nc 452 !!
32KB x 256Kn S+0 D+1 :	Na 530	Ma 858	Nb 468	Mb 858	Nc 468

64KB x 128Kn S+0 D+0 :	Na 452	Ma 858	Nb 437	Mb 858	Nc 437
64KB x 128Kn S+1 D+0 :	Na 624	Ma 1467	Nb 483	Mb 1467	Nc 499 !!
64KB x 128Kn S+0 D+1 :	Na 717	Ma 905	Nb 484	Mb 858	Nc 468
128KB x 64Kn S+0 D+1 :	Na 639	Ma 858	Nb 484	Mb 842	Nc 484
128KB x 64Kn S+0 D+1 :	Na 639	Ma 858	Nb 484	Mb 936	Nc 468
128KB x 64Kn S+1 D+0 :	Na 655	Ma 1482	Nb 468	Mb 1482	Nc 468
128KB x 64Kn S+1 D+0 :	Na 608	Ma 1482	Nb 468	Mb 1482	Nc 468
256KB x 32Kn S+0 D+1 :	Na 967	Ma 1108	Nb 795	Mb 1092	Nc 811
256KB x 32Kn S+0 D+1 :	Na 1014	Ma 1108	Nb 811	Mb 1107	Nc 796
512KB x 16Kn S+0 D+1 :	Na 998	Ma 1155	Nb 795	Mb 1108	Nc 796
512KB x 16Kn S+0 D+1 :	Na 983	Ma 1123	Nb 796	Mb 1107	Nc 812
512KB x 16Kn S+0 D+0 :	Na 858	Ma 1030	Nb 780	Mb 1045	Nc 780
1024KB x 8Kn S+0 D+1 :	Na 1139	Ma 1170	Nb 811	Mb 1107	Nc 812
1024KB x 8Kn S+0 D+1 :	Na 1014	Ma 1108	Nb 951	Mb 1108	Nc 827
2048KB x 4Kn S+0 D+1 :	Na 1045	Ma 1186	Nb 858	Mb 1185	Nc 858
2048KB x 4Kn S+0 D+0 :	Na 904	Ma 1139	Nb 812	Mb 1123	Nc 795
4096KB x 2Kn S+0 D+1 :	Na 1045	Ma 1170	Nb 874	Mb 1170	Nc 873 //
4096KB x 2Kn S+1 D+0 :	Na 1029	Ma 2044	Nb 827	Mb 2246	Nc 827 \\

2048KB x 4Kn S+1 D+0 :	Na 1014	Ma 2059	Nb 843	Mb 2044	Nc 842   //
1024KB x 8Kn S+1 D+0 :	Na 983	Ma 7114	Nb 795	Mb 6927	Nc 795 !!!?
1024KB x 8Kn S+1 D+0 :	Na 1107	Ma 6927	Nb 795	Mb 6958	Nc 811 !!!?
512KB x 16Kn S+1 D+0 :	Na 1030	Ma 1872	Nb 811	Mb 1888	Nc 795   \\

768KB x 10Kn S+1 D+0 :	Na 1061	Ma 1888	Nb 795	Mb 1857	Nc 795

1024KB x 8Kn S+1 D+0 :	Na 998	Ma 6927	Nb 795	Mb 6942	Nc 796 //
1024KB x 8Kn S+1 D+0 :	Na 967	Ma 6926	Nb 812	Mb 6926	Nc 811 !!!
1024KB x 8Kn S+0 D+1 :	Na 998	Ma 1108	Nb 826	Mb 1108	Nc 827 \\

2048KB x 4Kn S+0 D+1 :	Na 1061	Ma 1186	Nb 873	Mb 1186	Nc 874 +
2048KB x 4Kn S+1 D+0 :	Na 1092	Ma 2044	Nb 826	Mb 2059	Nc 843 +
CPU T7250
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
///Intel(R) Core(TM)2 Duo CPU     T7250  @ 2.00GHz

4KB x 2048Kn S+0 D+0 :	Na 421	Ma 1108	Nb 421	Mb 1108	Nc 421
4KB x 2048Kn S+1 D+0 :	Na 1310	Ma 6599	Nb 1264	Mb 6614	Nc 1279 !!!!
4KB x 2048Kn S+1 D+1 :	Na 421	Ma 1108	Nb 405	Mb 1108	Nc 421
4KB x 2048Kn S+0 D+1 :	Na 1731	Ma 1966	Nb 1700	Mb 1982	Nc 1700 ??
4KB x 2048Kn S+0 D+7 :	Na 1716	Ma 1965	Nb 1685	Mb 1966	Nc 1700 ??
4KB x 2048Kn S+0 D+8 :	Na 936	Ma 1092	Nb 921	Mb 1092	Nc 905
4KB x 2048Kn S+0 D+4 :	Na 1701	Ma 1950	Nb 1700	Mb 1950	Nc 1701
4KB x 2048Kn S+0 D+16 :	Na 671	Ma 1108	Nb 670	Mb 1092	Nc 671
4KB x 2048Kn S+16 D+0 :	Na 453	Ma 3198	Nb 421	Mb 3229	Nc 421
4KB x 2048Kn S+8 D+0 :	Na 577	Ma 6412	Nb 546	Mb 6411	Nc 562
4KB x 2048Kn S+4 D+0 :	Na 1326	Ma 6630	Nb 1264	Mb 6614	Nc 1295

128KB x 64Kn S+0 D+0 :	Na 983	Ma 1341	Nb 983	Mb 1342	Nc 982    //
128KB x 64Kn S+1 D+0 :	Na 1997	Ma 7519	Nb 2012	Mb 7520	Nc 2012 !!!
128KB x 64Kn S+0 D+1 :	Na 2293	Ma 2184	Nb 2278	Mb 2246	Nc 2340 ???
128KB x 64Kn S+0 D+1 :	Na 2278	Ma 2199	Nb 2262	Mb 2231	Nc 2278 ???
128KB x 64Kn S+0 D+1 :	Na 2278	Ma 2215	Nb 2278	Mb 2215	Nc 2278 ???
128KB x 64Kn S+0 D+1 :	Na 2309	Ma 2293	Nb 2324	Mb 2216	Nc 2277 ???

2KB x 4096Kn S+0 D+1 :	Na 1700	Ma 1950	Nb 1716	Mb 1966	Nc 1685
2KB x 4096Kn S+1 D+0 :	Na 1310	Ma 6630	Nb 1264	Mb 6599	Nc 1279 !!!!
2KB x 4096Kn S+0 D+0 :	Na 453	Ma 1154	Nb 421	Mb 1139	Nc 437

4KB x 2048Kn S+32 D+0 :	Na 422	Ma 1622	Nb 421	Mb 1607	Nc 421

64KB x 128Kn S+0 D+0 :	Na 1029	Ma 1342	Nb 998	Mb 1342	Nc 967
64KB x 128Kn S+0 D+1 :	Na 2309	Ma 2199	Nb 2278	Mb 2215	Nc 2278
64KB x 128Kn S+0 D+1 :	Na 2309	Ma 2215	Nb 2293	Mb 2184	Nc 2293
64KB x 128Kn S+1 D+0 :	Na 2028	Ma 7504	Nb 1981	Mb 7535	Nc 1997
64KB x 128Kn S+7 D+0 :	Na 2013	Ma 7519	Nb 2012	Mb 7504	Nc 2012
64KB x 128Kn S+15 D+0 :	Na 2044	Ma 7503	Nb 2028	Mb 7520	Nc 2043

64KB x 128Kn S+0 D+0 :	Na 983	Ma 1326	Nb 999	Mb 1326	Nc 982
64KB x 128Kn S+8 D+0 :	Na 1201	Ma 6443	Nb 1201	Mb 6474	Nc 1202 ?!?!?!?
64KB x 128Kn S+16 D+0 :	Na 983	Ma 3229	Nb 983	Mb 3229	Nc 983
64KB x 128Kn S+24 D+0 :	Na 1217	Ma 2230	Nb 1186	Mb 2215	Nc 1217 !!
64KB x 128Kn S+32 D+0 :	Na 983	Ma 1903	Nb 967	Mb 1888	Nc 967
64KB x 128Kn S+40 D+0 :	Na 1217	Ma 1731	Nb 1201	Mb 1716	Nc 1202 !!
64KB x 128Kn S+48 D+0 :	Na 983	Ma 1653	Nb 968	Mb 1653	Nc 983
64KB x 128Kn S+56 D+0 :	Na 1217	Ma 1575	Nb 1217	Mb 1591	Nc 1217 !!
64KB x 128Kn S+64 D+0 :	Na 998	Ma 1560	Nb 983	Mb 1544	Nc 983

64KB x 128Kn S+57 D+0 :	Na 2044	Ma 2792	Nb 2012	Mb 2777	Nc 2028
64KB x 128Kn S+0 D+57 :	Na 2324	Ma 2216	Nb 2308	Mb 2184	Nc 2325
64KB x 128Kn S+0 D+9 :	Na 2277	Ma 2200	Nb 2293	Mb 2200	Nc 2262
64KB x 128Kn S+0 D+1 :	Na 2278	Ma 2230	Nb 2262	Mb 2216	Nc 2277
64KB x 128Kn S+9 D+1 :	Na 1216	Ma 6396	Nb 1202	Mb 6489	Nc 1201 ?!?!?!?
64KB x 128Kn S+9 D+0 :	Na 2028	Ma 7535	Nb 2044	Mb 7535	Nc 2043

64KB x 128Kn S+65 D+0 :	Na 2012	Ma 2793	Nb 1996	Mb 2777	Nc 2013 ! !
64KB x 128Kn S+1 D+0 :	Na 2012	Ma 7519	Nb 2013	Mb 7550	Nc 1981 ?!?!?!?
64KB x 128Kn S+0 D+1 :	Na 2294	Ma 2199	Nb 2293	Mb 2200	Nc 2293 !
64KB x 128Kn S+0 D+65 :	Na 2247	Ma 2215	Nb 2246	Mb 2215	Nc 2216 !

64KB x 128Kn S+8 D+0 :	Na 1170	Ma 6147	Nb 1154	Mb 6147	Nc 1154 !!!!
64KB x 128Kn S+8 D+0 :	Na 1185	Ma 6272	Nb 1154	Mb 6147	Nc 1154 !!!!

128KB x 64Kn S+0 D+1 :	Na 2231	Ma 2091	Nb 2184	Mb 2106	Nc 2168
128KB x 64Kn S+0 D+2 :	Na 2200	Ma 2106	Nb 2168	Mb 2106	Nc 2169
128KB x 64Kn S+0 D+3 :	Na 2200	Ma 2153	Nb 2215	Mb 2106	Nc 2168
128KB x 64Kn S+0 D+4 :	Na 2247	Ma 2121	Nb 2184	Mb 2106	Nc 2184
128KB x 64Kn S+0 D+5 :	Na 2246	Ma 2137	Nb 2184	Mb 2106	Nc 2169
128KB x 64Kn S+0 D+8 :	Na 1279	Ma 1279	Nb 1248	Mb 1279	Nc 1248
128KB x 64Kn S+0 D+9 :	Na 2199	Ma 2091	Nb 2168	Mb 2106	Nc 2168
128KB x 64Kn S+0 D+16 :	Na 1186	Ma 1310	Nb 1155	Mb 1263	Nc 1155

4KB x 2048Kn S+0 D+0 :	Na 421	Ma 1108	Nb 421	Mb 1108	Nc 421
4KB x 2048Kn S+1 D+0 :	Na 1310	Ma 6599	Nb 1264	Mb 6614	Nc 1279 !!!!
4KB x 2048Kn S+1 D+1 :	Na 421	Ma 1108	Nb 405	Mb 1108	Nc 421
4KB x 2048Kn S+0 D+1 :	Na 1731	Ma 1966	Nb 1700	Mb 1982	Nc 1700 ??
4KB x 2048Kn S+0 D+7 :	Na 1716	Ma 1965	Nb 1685	Mb 1966	Nc 1700 ??
4KB x 2048Kn S+0 D+8 :	Na 936	Ma 1092	Nb 921	Mb 1092	Nc 905
4KB x 2048Kn S+0 D+4 :	Na 1701	Ma 1950	Nb 1700	Mb 1950	Nc 1701
4KB x 2048Kn S+0 D+16 :	Na 671	Ma 1108	Nb 670	Mb 1092	Nc 671
4KB x 2048Kn S+16 D+0 :	Na 453	Ma 3198	Nb 421	Mb 3229	Nc 421
4KB x 2048Kn S+8 D+0 :	Na 577	Ma 6412	Nb 546	Mb 6411	Nc 562
4KB x 2048Kn S+4 D+0 :	Na 1326	Ma 6630	Nb 1264	Mb 6614	Nc 1295

128KB x 64Kn S+0 D+0 :	Na 983	Ma 1341	Nb 983	Mb 1342	Nc 982    //
128KB x 64Kn S+1 D+0 :	Na 1997	Ma 7519	Nb 2012	Mb 7520	Nc 2012 !!!
128KB x 64Kn S+0 D+1 :	Na 2293	Ma 2184	Nb 2278	Mb 2246	Nc 2340 ???
128KB x 64Kn S+0 D+1 :	Na 2278	Ma 2199	Nb 2262	Mb 2231	Nc 2278 ???
128KB x 64Kn S+0 D+1 :	Na 2278	Ma 2215	Nb 2278	Mb 2215	Nc 2278 ???
128KB x 64Kn S+0 D+1 :	Na 2309	Ma 2293	Nb 2324	Mb 2216	Nc 2277 ???

2KB x 4096Kn S+0 D+1 :	Na 1700	Ma 1950	Nb 1716	Mb 1966	Nc 1685
2KB x 4096Kn S+1 D+0 :	Na 1310	Ma 6630	Nb 1264	Mb 6599	Nc 1279 !!!!
2KB x 4096Kn S+0 D+0 :	Na 453	Ma 1154	Nb 421	Mb 1139	Nc 437

4KB x 2048Kn S+32 D+0 :	Na 422	Ma 1622	Nb 421	Mb 1607	Nc 421

64KB x 128Kn S+0 D+0 :	Na 1029	Ma 1342	Nb 998	Mb 1342	Nc 967
64KB x 128Kn S+0 D+1 :	Na 2309	Ma 2199	Nb 2278	Mb 2215	Nc 2278
64KB x 128Kn S+0 D+1 :	Na 2309	Ma 2215	Nb 2293	Mb 2184	Nc 2293
64KB x 128Kn S+1 D+0 :	Na 2028	Ma 7504	Nb 1981	Mb 7535	Nc 1997
64KB x 128Kn S+7 D+0 :	Na 2013	Ma 7519	Nb 2012	Mb 7504	Nc 2012
64KB x 128Kn S+15 D+0 :	Na 2044	Ma 7503	Nb 2028	Mb 7520	Nc 2043

64KB x 128Kn S+0 D+0 :	Na 983	Ma 1326	Nb 999	Mb 1326	Nc 982
64KB x 128Kn S+8 D+0 :	Na 1201	Ma 6443	Nb 1201	Mb 6474	Nc 1202
64KB x 128Kn S+16 D+0 :	Na 983	Ma 3229	Nb 983	Mb 3229	Nc 983
64KB x 128Kn S+24 D+0 :	Na 1217	Ma 2230	Nb 1186	Mb 2215	Nc 1217
64KB x 128Kn S+32 D+0 :	Na 983	Ma 1903	Nb 967	Mb 1888	Nc 967
64KB x 128Kn S+40 D+0 :	Na 1217	Ma 1731	Nb 1201	Mb 1716	Nc 1202
64KB x 128Kn S+48 D+0 :	Na 983	Ma 1653	Nb 968	Mb 1653	Nc 983
64KB x 128Kn S+56 D+0 :	Na 1217	Ma 1575	Nb 1217	Mb 1591	Nc 1217
64KB x 128Kn S+64 D+0 :	Na 998	Ma 1560	Nb 983	Mb 1544	Nc 983

64KB x 128Kn S+57 D+0 :	Na 2044	Ma 2792	Nb 2012	Mb 2777	Nc 2028
64KB x 128Kn S+0 D+57 :	Na 2324	Ma 2216	Nb 2308	Mb 2184	Nc 2325
64KB x 128Kn S+0 D+9 :	Na 2277	Ma 2200	Nb 2293	Mb 2200	Nc 2262
64KB x 128Kn S+0 D+1 :	Na 2278	Ma 2230	Nb 2262	Mb 2216	Nc 2277
64KB x 128Kn S+9 D+1 :	Na 1216	Ma 6396	Nb 1202	Mb 6489	Nc 1201
64KB x 128Kn S+9 D+0 :	Na 2028	Ma 7535	Nb 2044	Mb 7535	Nc 2043

64KB x 128Kn S+65 D+0 :	Na 2012	Ma 2793	Nb 1996	Mb 2777	Nc 2013 !
64KB x 128Kn S+1 D+0 :	Na 2012	Ma 7519	Nb 2013	Mb 7550	Nc 1981 ?!?!?!?
64KB x 128Kn S+0 D+1 :	Na 2294	Ma 2199	Nb 2293	Mb 2200	Nc 2293 !
64KB x 128Kn S+0 D+65 :	Na 2247	Ma 2215	Nb 2246	Mb 2215	Nc 2216 !

4KB x 2048Kn S+0 D+0 :	Na 453	Ma 1107	Nb 421	Mb 1092	Nc 422
4KB x 2048Kn S+0 D+0 :	Na 437	Ma 1107	Nb 437	Mb 1092	Nc 406

-------  x32   ------------------------------------------------

1KB x 8192Kn S+0 D+0 :	Na 390	Ma 1170	Nb 390	Mb 1170	Nc 375
1KB x 8192Kn S+0 D+0 :	Na 406	Ma 1170	Nb 374	Mb 1170	Nc 374
1KB x 8192Kn S+0 D+0 :	Na 406	Ma 1170	Nb 374	Mb 1170	Nc 390
1KB x 8192Kn S+0 D+0 :	Na 405	Ma 1170	Nb 375	Mb 1170	Nc 374
1KB x 8192Kn S+0 D+0 :	Na 406	Ma 1170	Nb 374	Mb 1170	Nc 390

8KB x 1024Kn S+0 D+0 :	Na 343	Ma 1045	Nb 344	Mb 1045	Nc 327
8KB x 1024Kn S+0 D+0 :	Na 359	Ma 1061	Nb 327	Mb 1045	Nc 344
8KB x 1024Kn S+0 D+0 :	Na 359	Ma 1092	Nb 343	Mb 1076	Nc 344

1KB x 8192Kn S+0 D+0 :	Na 422	Ma 1216	Nb 406	Mb 1201	Nc 390
4KB x 2048Kn S+0 D+0 :	Na 374	Ma 1108	Nb 343	Mb 1108	Nc 358
8KB x 1024Kn S+0 D+0 :	Na 358	Ma 1092	Nb 359	Mb 1092	Nc 359
16KB x 512Kn S+0 D+0 :	Na 422	Ma 1092	Nb 405	Mb 1092	Nc 421

32KB x 256Kn S+0 D+0 :	Na 1029	Ma 1342	Nb 998	Mb 1326	Nc 999 
64KB x 128Kn S+0 D+0 :	Na 1014	Ma 1342	Nb 983	Mb 1341	Nc 999
128KB x 64Kn S+0 D+0 :	Na 1014	Ma 1326	Nb 998	Mb 1342	Nc 998
256KB x 32Kn S+0 D+0 :	Na 1014	Ma 1326	Nb 998	Mb 1326	Nc 999
512KB x 16Kn S+0 D+0 :	Na 1077	Ma 1388	Nb 1045	Mb 1373	Nc 1030
768KB x 10Kn S+0 D+0 :	Na 1435	Ma 1872	Nb 1435	Mb 1904	Nc 1388

1024KB x 8Kn S+0 D+0 :	Na 2355	Ma 2871	Nb 2293	Mb 2886	Nc 2574
2048KB x 4Kn S+0 D+0 :	Na 6630	Ma 6864	Nb 6661	Mb 6864	Nc 6646
4096KB x 2Kn S+0 D+0 :	Na 6614	Ma 6786	Nb 6599	Mb 6802	Nc 6599

4KB x 2048Kn S+0 D+0 :	Na 375	Ma 1076	Nb 343	Mb 1092	Nc 359
4KB x 2048Kn S+1 D+0 :	Na 1280	Ma 2308	Nb 1264	Mb 2309	Nc 1248
4KB x 2048Kn S+0 D+1 :	Na 1669	Ma 9953	Nb 1653	Mb 9938	Nc 1638  !
4KB x 2048Kn S+0 D+1 :	Na 1685	Ma 9906	Nb 1653	Mb 9938	Nc 1653  !

1KB x 8192Kn S+0 D+0 :	Na 390	Ma 1170	Nb 390	Mb 1170	Nc 375 
1KB x 8192Kn S+0 D+1 :	Na 1653	Ma 9844	Nb 1638	Mb 9859	Nc 1638  !
1KB x 8192Kn S+1 D+0 :	Na 1326	Ma 2356	Nb 1295	Mb 2355	Nc 1295

64KB x 128Kn S+0 D+0 :	Na 1045	Ma 1311	Nb 998	Mb 1326	Nc 999
64KB x 128Kn S+1 D+0 :	Na 2074	Ma 2606	Nb 2074	Mb 2621	Nc 2059
64KB x 128Kn S+0 D+1 :	Na 2278	Ma 10514Nb 2293	Mb 10562Nc 2246  !!
Pentium(R) 4 CPU 3.00GHz
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
///Intel(R) Pentium(R) 4 CPU 3.00GHz

-------  x32   -----------------------------------------------

1KB x 8192Kn S+0 D+0 :	Na 860	Ma 1484	Nb 860	Mb 1515	Nc 860
2KB x 4096Kn S+0 D+0 :	Na 844	Ma 1406	Nb 844	Mb 1390	Nc 844
4KB x 2048Kn S+0 D+0 :	Na 828	Ma 1453	Nb 828	Mb 1657	Nc 843
4KB x 2048Kn S+0 D+0 :	Na 844	Ma 1390	Nb 828	Mb 1407	Nc 828
4KB x 2048Kn S+1 D+0 :	Na 1563	Ma 1859	Nb 1531	Mb 1844	Nc 1547
4KB x 2048Kn S+0 D+1 :	Na 1531	Ma 1844	Nb 1547	Mb 1828	Nc 1531

8KB x 1024Kn S+0 D+1 :	Na 1531	Ma 2016	Nb 1516	Mb 2015	Nc 1516
8KB x 1024Kn S+1 D+0 :	Na 1594	Ma 2000	Nb 1563	Mb 2000	Nc 1578
8KB x 1024Kn S+16 D+0 :	Na 859	Ma 1453	Nb 860	Mb 1453	Nc 828
8KB x 1024Kn S+8 D+0 :	Na 843	Ma 1500	Nb 860	Mb 1468	Nc 860
8KB x 1024Kn S+4 D+0 :	Na 1594	Ma 2016	Nb 1562	Mb 2000	Nc 1594
8KB x 1024Kn S+0 D+8 :	Na 875	Ma 2031	Nb 875	Mb 2047	Nc 875
8KB x 1024Kn S+0 D+16 :	Na 828	Ma 1922	Nb 828	Mb 1922	Nc 828
8KB x 1024Kn S+0 D+20 :	Na 1469	Ma 1906	Nb 1469	Mb 1922	Nc 1468

16KB x 512Kn S+0 D+0 :	Na 1015	Ma 1782	Nb 1000	Mb 1781	Nc 1000
32KB x 256Kn S+0 D+0 :	Na 1016	Ma 1750	Nb 1015	Mb 1766	Nc 1000
64KB x 128Kn S+0 D+0 :	Na 1016	Ma 1750	Nb 1015	Mb 1750	Nc 1016
128KB x 64Kn S+0 D+0 :	Na 1000	Ma 1765	Nb 1000	Mb 1782	Nc 1000
256KB x 32Kn S+0 D+0 :	Na 1000	Ma 1797	Nb 1000	Mb 1797	Nc 1016
512KB x 16Kn S+0 D+0 :	Na 1218	Ma 1985	Nb 1203	Mb 1984	Nc 1203
1024KB x 8Kn S+0 D+0 :	Na 7515	Ma 7579	Nb 7531	Mb 7687	Nc 7641
2048KB x 4Kn S+0 D+0 :	Na 7453	Ma 7562	Nb 7454	Mb 7546	Nc 7469

4KB x 2048Kn S+0 D+0 :	Na 844	Ma 1390	Nb 828	Mb 1407	Nc 828
4KB x 2048Kn S+8 D+0 :	Na 844	Ma 1391	Nb 843	Mb 1375	Nc 829
4KB x 2048Kn S+0 D+8 :	Na 844	Ma 1875	Nb 844	Mb 1890	Nc 860
4KB x 2048Kn S+16 D+0 :	Na 828	Ma 1375	Nb 828	Mb 1375	Nc 844
4KB x 2048Kn S+0 D+16 :	Na 828	Ma 1797	Nb 828	Mb 1797	Nc 812

128KB x 64Kn S+0 D+8 :	Na 1141	Ma 2391	Nb 1125	Mb 2343	Nc 1125
128KB x 64Kn S+8 D+0 :	Na 1140	Ma 1782	Nb 1125	Mb 1797	Nc 1125
128KB x 64Kn S+16 D+0 :	Na 984	Ma 1797	Nb 984	Mb 1782	Nc 984
128KB x 64Kn S+0 D+16 :	Na 1031	Ma 2313	Nb 1016	Mb 2359	Nc 1031
128KB x 64Kn S+17 D+1 :	Na 859	Ma 1766	Nb 859	Mb 1766	Nc 844
128KB x 64Kn S+1 D+1 :	Na 1000	Ma 1750	Nb 985	Mb 1765	Nc 985
128KB x 64Kn S+1 D+1 :	Na 984	Ma 1766	Nb 984	Mb 1750	Nc 984
128KB x 64Kn S+1 D+17 :	Na 953	Ma 2313	Nb 953	Mb 2328	Nc 953
128KB x 64Kn S+9 D+17 :	Na 1218	Ma 2360	Nb 1203	Mb 2375	Nc 1203
128KB x 64Kn S+9 D+25 :	Na 953	Ma 2297	Nb 938	Mb 2281	Nc 953
128KB x 64Kn S+25 D+9 :	Na 860	Ma 1750	Nb 843	Mb 1735	Nc 859
...
Рейтинг: 0 / 0
Ну очень быстрый Move() для x86/x64
    #38780609
SoftGuest
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Честно говоря я не совсем понял, как работает тест и какой именно "стандартный Move" фигурирует (похоже самый быстрый x86)... Но судя по результатам я бог оптимизаций :). Хотя по большому счёту увеличение производительности в полтора-два раза вполне ожидаемо
...
Рейтинг: 0 / 0
Ну очень быстрый Move() для x86/x64
    #38806952
Корбен
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
asviridenkovСлабо улучшить?
Сначала подправим логику
1) неправильный результат выдают "x32" версии PStrScan для параметров (NotNil, '1', 0)
2) неплохо бы защититься от отрицательного size:
Код: plaintext
1.
2.
        TEST    ECX,ECX   //ASize=0?
        J L E     @@qt

Теперь о производительности. Думаю, что результаты сильно зависят от железа, но у меня следующий пример быстрее. Чем короче строка, тем больше разница (до 6 раз). На длинных строках - паритет.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
function Q_PStrScan(P: PWideChar; Ch: WideChar; Size: Integer): Integer; // x32
asm
  test    eax, eax   // P=nil?
  jz      @@exit

  push    ecx
  lea     eax, [eax + 2*ecx]
  neg     ecx
  jnl     @@zero

@@loop:
  cmp dx, [eax + 2*ecx]
  je @@found

  inc ecx
  jne @@loop

@@zero:
  pop ecx
  xor eax, eax
@@exit:
  ret

@@found:
  pop eax
  lea eax, [eax + ecx + 1]
end;
...
Рейтинг: 0 / 0
Ну очень быстрый Move() для x86/x64
    #38806961
Фотография defecator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Корбенно у меня следующий пример быстрее. Чем короче строка, тем больше разница (до 6 раз). На длинных строках - паритет.
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
function Q_PStrScan(P: PWideChar; Ch: WideChar; Size: Integer): Integer; // x32
asm
  test    eax, eax   // P=nil?
  jz      @@exit

  push    ecx
  lea     eax, [eax + 2*ecx]
  neg     ecx
  jnl     @@zero

@@loop:
  cmp dx, [eax + 2*ecx]
  je @@found

  inc ecx
  jne @@loop

@@zero:
  pop ecx
  xor eax, eax
@@exit:
  ret

@@found:
  pop eax
  lea eax, [eax + ecx + 1]
end;



Это же код из библиотеки QStrings, так нечестно ))
...
Рейтинг: 0 / 0
Период между сообщениями больше года.
Ну очень быстрый Move() для x86/x64
    #39544651
Няшик
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну очень быстрый Move - самый простой

Вот этот, без использования SSE будет быстрее стандартного Move и NonCollisionMove

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
function MyMove(const Source; var Dest; Count: NativeInt): Integer;
asm
  push ebx
  cmp ecx, 15
  jbe @@Move8
@@Move16:
  mov ebx, DWORD PTR [eax]
  mov DWORD PTR [edx], ebx
  mov ebx, DWORD PTR [eax+4]
  mov DWORD PTR [edx+4], ebx
  add edx, 16
  add eax, 16
  sub ecx, 16
  cmp ecx, 15
  ja @@Move16
@@Move8:
  test ecx, ecx
  je @@Exit
  test cl, 8
  je @@Move4
  mov ebx, DWORD PTR [eax]
  mov DWORD PTR [edx], ebx
  add edx, 8
  add eax, 8
@@Move4:
  test cl, 4
  je @@Move2
  mov ebx, DWORD PTR [eax]
  mov DWORD PTR [edx], ebx
  add edx, 4
  add eax, 4
@@Move2:
  test cl, 2
  je @@Move1
  movzx ebx, WORD PTR [eax]
  mov WORD PTR [edx], bx
  add edx, 2
  add eax, 2
@@Move1:
  test cl, 1
  je @@Exit
  movzx eax, BYTE PTR [eax]
  mov BYTE PTR [edx], al
@@Exit:
  pop ebx
end;




Сам тестер
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
264.
265.
266.
267.
268.
269.
270.
271.
272.
273.
274.
275.
276.
277.
278.
279.
280.
281.
282.
283.
284.
285.
286.
287.
288.
289.
290.
291.
292.
293.
294.
295.
296.
297.
298.
299.
300.
301.
302.
303.
304.
305.
306.
307.
308.
309.
310.
311.
312.
313.
314.
315.
316.
317.
318.
319.
320.
321.
322.
323.
324.
325.
326.
327.
328.
329.
330.
331.
332.
333.
334.
335.
336.
337.
338.
339.
340.
341.
342.
343.
344.
345.
346.
347.
348.
349.
350.
351.
352.
353.
354.
355.
356.
357.
358.
359.
360.
361.
362.
363.
364.
365.
366.
367.
368.
369.
370.
371.
372.
373.
374.
375.
376.
377.
378.
379.
380.
381.
382.
383.
384.
385.
386.
387.
388.
389.
390.
391.
392.
393.
394.
395.
396.
397.
398.
399.
400.
401.
402.
403.
404.
405.
406.
407.
408.
409.
410.
411.
412.
413.
414.
415.
416.
417.
418.
419.
420.
421.
422.
423.
424.
425.
426.
427.
428.
429.
430.
431.
432.
433.
434.
435.
436.
437.
438.
439.
440.
441.
442.
443.
444.
445.
446.
447.
448.
449.
450.
451.
452.
453.
454.
455.
456.
457.
458.
459.
460.
461.
462.
463.
464.
465.
466.
467.
468.
469.
470.
471.
472.
473.
474.
475.
476.
477.
478.
479.
480.
481.
482.
483.
484.
485.
486.
487.
488.
489.
490.
491.
492.
493.
494.
495.
496.
497.
498.
499.
500.
501.
502.
503.
504.
505.
506.
507.
508.
509.
510.
511.
512.
513.
514.
515.
516.
517.
518.
519.
520.
program Project71;

uses
  Windows;

function sprintf(S: PAnsiChar; const Format: PAnsiChar): Integer; cdecl;
  varargs; external 'msvcrt.dll';
function QueryPerformanceCounter(var lpPerformanceCount: Int64): LongBool;
  stdcall; external 'kernel32.dll' name 'QueryPerformanceCounter';
function QueryPerformanceFrequency(var lpFrequency: Int64): LongBool; stdcall;
  external 'kernel32.dll' name 'QueryPerformanceFrequency';

function PrintTime(time: Single): AnsiString;
begin
  Result := '';
  SetLength(Result, 25);
  SetLength(Result, sprintf(PAnsiChar(Result), '%f', time));
end;

function MyMove(const Source; var Dest; Count: NativeInt): Integer;
asm
  push ebx
  cmp ecx, 15
  jbe @@Move8
@@Move16:
  mov ebx, DWORD PTR [eax]
  mov DWORD PTR [edx], ebx
  mov ebx, DWORD PTR [eax+4]
  mov DWORD PTR [edx+4], ebx
  add edx, 16
  add eax, 16
  sub ecx, 16
  cmp ecx, 15
  ja @@Move16
@@Move8:
  test ecx, ecx
  je @@Exit
  test cl, 8
  je @@Move4
  mov ebx, DWORD PTR [eax]
  mov DWORD PTR [edx], ebx
  add edx, 8
  add eax, 8
@@Move4:
  test cl, 4
  je @@Move2
  mov ebx, DWORD PTR [eax]
  mov DWORD PTR [edx], ebx
  add edx, 4
  add eax, 4
@@Move2:
  test cl, 2
  je @@Move1
  movzx ebx, WORD PTR [eax]
  mov WORD PTR [edx], bx
  add edx, 2
  add eax, 2
@@Move1:
  test cl, 1
  je @@Exit
  movzx eax, BYTE PTR [eax]
  mov BYTE PTR [edx], al
@@Exit:
  pop ebx
end;

procedure NonCollisionMove(const Source; var Dest; const size: NativeUInt);
asm
  // basic routine
  {$IFDEF CPUX86}
  cmp ecx, 32
  {$ELSE .CPUX64}
  cmp r8, 32
  // make Source = eax/rax, Dest = edx/rdx, Size = ecx/rcx
  mov rax, rcx
  xchg rcx, r8
  // r9 as pointer to @move_03_items
  lea r9, [@move_03_items]
  {$ENDIF}

  // is big/large (32...inf)
  jae @move_big

  // is small (0..3)
  cmp ecx, 4
  jb @move_03

  // move middle(4..31) = move 16(0..16) + move dwords(0..12) + move small(0..3)
  cmp ecx, 16
  jb @move_015

  {$IFDEF CPUX86}
  movups xmm0, [eax]
  movups [edx], xmm0
  jne @move_015_offset
  ret
@move_015_offset:
  sub ecx, 16
  add eax, 16
  add edx, 16
@move_015:
  push ecx
  and ecx, -4
  add eax, ecx
  add edx, ecx
  jmp [ecx + @move_dwords]
@move_dwords: DD @rw_0,@rw_4,@rw_8,@rw_12
@rw_12:
  mov ecx, [eax-12]
  mov [edx-12], ecx
@rw_8:
  mov ecx, [eax-8]
  mov [edx-8], ecx
@rw_4:
  mov ecx, [eax-4]
  mov [edx-4], ecx
@rw_0:
  pop ecx
  and ecx, 3
  {$ELSE .CPUX64}
  movups xmm0, [rax]
  movups [rdx], xmm0
  jne @move_015_offset
  ret
@move_015_offset:
  sub rcx, 16
  add rax, 16
  add rdx, 16
@move_015:
  // make r9 = dest 0..3 pointer, rcx = dwords count
  mov r8, rcx
  shr rcx, 2
  and r8, 3
  lea r9, [r9 + r8*8]
  // case jump
  lea r8, [@move_dwords]
  jmp qword ptr [r8 + rcx*8]
@move_dwords: DQ @rw_0,@rw_4,@rw_8,@rw_12
@rw_8:
  mov rcx, [rax]
  mov [rdx], rcx
  add rax, 8
  add rdx, 8
  jmp qword ptr [r9]
@rw_12:
  mov rcx, [rax]
  mov [rdx], rcx
  add rax, 8
  add rdx, 8
@rw_4:
  mov ecx, [rax]
  mov [rdx], ecx
  add rax, 4
  add rdx, 4
@rw_0:
  jmp qword ptr [r9]
  {$ENDIF}

@move_03:
  {$IFDEF CPUX86}
  jmp [offset @move_03_items + ecx*4]
@move_03_items: DD @0,@1,@2,@3
@2: mov cx, [eax]
  mov [edx], cx
  ret
@3: mov cx, [eax]
  mov [edx], cx
  add eax, 2
  add edx, 2
@1: mov cl, [eax]
  mov [edx], cl
@0: ret
  {$ELSE .CPUX64}
  jmp qword ptr [r9 + rcx*8]
@move_03_items: DQ @0,@1,@2,@3
@2: mov cx, [rax]
  mov [rdx], cx
  ret
@3: mov cx, [rax]
  mov [rdx], cx
  add rax, 2
  add rdx, 2
@1: mov cl, [rax]
  mov [rdx], cl
@0: ret
  {$ENDIF}

@move_big:
  {$IFDEF CPUX86}
  cmp ecx, 16*4
  {$ELSE .CPUX64}
  cmp rcx, 16*4
  {$ENDIF}
  jae @move_large

  // big memory move by SSE (32..63) = (32..48) + (0..15)
  {$IFDEF CPUX86}
  test ecx, 15
  jz @move_32_48

  push ecx
  and ecx, 15
  movups xmm0, [eax]
  movups [edx], xmm0
  add eax, ecx
  add edx, ecx

  pop ecx
  and ecx, -16
  {$ELSE .CPUX64}
  mov r8, rcx
  test rcx, 15
  jz @move_32_48

  and r8, 15
  movups xmm0, [rax]
  movups [rdx], xmm0
  add rax, r8
  add rdx, r8

  and rcx, -16
  {$ENDIF}

@move_32_48:
  {$IFDEF CPUX86}
  add eax, ecx
  add edx, ecx
  cmp ecx, 48
  jb @rw_32
@rw_48: movups xmm2, [eax - 2*16 - 16]
  movups [edx - 2*16 - 16], xmm2
@rw_32: movups xmm1, [eax - 1*16 - 16]
  movups xmm0, [eax - 0*16 - 16]
  movups [edx - 1*16 - 16], xmm1
  movups [edx - 0*16 - 16], xmm0
  {$ELSE .CPUX64}
  add rax, rcx
  add rdx, rcx
  cmp rcx, 48
  jb @rw_32
@rw_48: movups xmm2, [rax - 2*16 - 16]
  movups [rdx - 2*16 - 16], xmm2
@rw_32: movups xmm1, [rax - 1*16 - 16]
  movups xmm0, [rax - 0*16 - 16]
  movups [rdx - 1*16 - 16], xmm1
  movups [rdx - 0*16 - 16], xmm0
  {$ENDIF}

  ret
@move_large:
  // large memory move by SSE (64..inf)

  // destination alignment
  {$IFDEF CPUX86}
  push ebx
  test edx, 15
  jz @move_16128_initialize

  mov ebx, edx
  movups xmm0, [eax]
  movups [ebx], xmm0

  add edx, 15
  and edx, -16
  sub ebx, edx
  sub eax, ebx
  add ecx, ebx
  {$ELSE .CPUX64}
  test rdx, 15
  jz @move_16128_initialize

  mov r8, rdx
  movups xmm0, [rax]
  movups [r8], xmm0

  add rdx, 15
  and rdx, -16
  sub r8, rdx
  sub rax, r8
  add rcx, r8
  {$ENDIF}

@move_16128_initialize:
  {$IFDEF CPUX86}
  push ecx
  mov ebx, offset @aligned_reads
  shr ecx, 4
  test eax, 15
  jz @move_16128
  mov ebx, offset @unaligned_reads
  {$ELSE .CPUX64}
  movaps [rsp-8-16], xmm6
  movaps [rsp-8-32], xmm7
  mov r8, rcx
  lea r9, [@aligned_reads]
  shr rcx, 4
  test rax, 15
  jz @move_16128
  lea r9, [@unaligned_reads]
  {$ENDIF}

@move_16128:
  {$IFDEF CPUX86}
  cmp ecx, 8
  jae @move_128

  lea ecx, [ecx + ecx]
  lea eax, [eax + ecx*8]
  lea edx, [edx + ecx*8]
  lea ebx, [ebx + 8*4]
  neg ecx
  lea ebx, [ebx + ecx*2]
  jmp ebx
@move_128:
  lea eax, [eax + 128]
  lea edx, [edx + 128]
  lea ecx, [ecx - 8]
  jmp ebx
  {$ELSE .CPUX64}
  cmp rcx, 8
  jae @move_128

  lea rcx, [rcx + rcx]
  lea rax, [rax + rcx*8]
  lea rdx, [rdx + rcx*8]
  lea r9, [r9 + 8*4]
  neg rcx
  lea r9, [r9 + rcx*2]
  jmp r9
@move_128:
  lea rax, [rax + 128]
  lea rdx, [rdx + 128]
  lea rcx, [rcx - 8]
  jmp r9
  {$ENDIF}

  // aligned sse read
@aligned_reads:
  {$IFDEF CPUX86}
  movaps xmm7, [eax - 7*16 - 16]
  movaps xmm6, [eax - 6*16 - 16]
  movaps xmm5, [eax - 5*16 - 16]
  movaps xmm4, [eax - 4*16 - 16]
  movaps xmm3, [eax - 3*16 - 16]
  movaps xmm2, [eax - 2*16 - 16]
  movaps xmm1, [eax - 1*16 - 16]
  movaps xmm0, [eax - 0*16 - 16]
  {$ELSE .CPUX64}
  movaps xmm7, [rax - 7*16 - 16]
  movaps xmm6, [rax - 6*16 - 16]
  movaps xmm5, [rax - 5*16 - 16]
  movaps xmm4, [rax - 4*16 - 16]
  movaps xmm3, [rax - 3*16 - 16]
  movaps xmm2, [rax - 2*16 - 16]
  movaps xmm1, [rax - 1*16 - 16]
  movaps xmm0, [rax - 0*16 - 16]
  {$ENDIF}
  jae @aligned_writes
  jmp @write_16112

  // unaligned sse read
@unaligned_reads:
  {$IFDEF CPUX86}
  movups xmm7, [eax - 7*16 - 16]
  movups xmm6, [eax - 6*16 - 16]
  movups xmm5, [eax - 5*16 - 16]
  movups xmm4, [eax - 4*16 - 16]
  movups xmm3, [eax - 3*16 - 16]
  movups xmm2, [eax - 2*16 - 16]
  movups xmm1, [eax - 1*16 - 16]
  movups xmm0, [eax - 0*16 - 16]
  jae @aligned_writes
@write_16112:
  lea ebx, [offset @aligned_writes + 8*4 + ecx*2]
  jmp ebx
  {$ELSE .CPUX64}
  movups xmm7, [rax - 7*16 - 16]
  movups xmm6, [rax - 6*16 - 16]
  movups xmm5, [rax - 5*16 - 16]
  movups xmm4, [rax - 4*16 - 16]
  movups xmm3, [rax - 3*16 - 16]
  movups xmm2, [rax - 2*16 - 16]
  movups xmm1, [rax - 1*16 - 16]
  movups xmm0, [rax - 0*16 - 16]
  jae @aligned_writes
@write_16112:
  lea r9, [@aligned_writes + 8*4]
  lea r9, [r9 + rcx*2]
  jmp r9
  {$ENDIF}

  // aligned sse write, loop
@aligned_writes:
  {$IFDEF CPUX86}
  movaps [edx - 7*16 - 16], xmm7
  movaps [edx - 6*16 - 16], xmm6
  movaps [edx - 5*16 - 16], xmm5
  movaps [edx - 4*16 - 16], xmm4
  movaps [edx - 3*16 - 16], xmm3
  movaps [edx - 2*16 - 16], xmm2
  movaps [edx - 1*16 - 16], xmm1
  movaps [edx - 0*16 - 16], xmm0
  test ecx, ecx
  {$ELSE .CPUX64}
  movaps [rdx - 7*16 - 16], xmm7
  movaps [rdx - 6*16 - 16], xmm6
  movaps [rdx - 5*16 - 16], xmm5
  movaps [rdx - 4*16 - 16], xmm4
  movaps [rdx - 3*16 - 16], xmm3
  movaps [rdx - 2*16 - 16], xmm2
  movaps [rdx - 1*16 - 16], xmm1
  movaps [rdx - 0*16 - 16], xmm0
  test rcx, rcx
  {$ENDIF}
  jg @move_16128

  // last 0..15 bytes
  {$IFDEF CPUX86}
  pop ecx
  pop ebx
  and ecx, 15
  jnz @move_115
  ret
@move_115:
  add eax, ecx
  add edx, ecx
  movups xmm0, [eax - 0*16 - 16]
  movups [edx - 0*16 - 16], xmm0
  {$ELSE .CPUX64}
  movaps xmm6, [rsp-8-16]
  movaps xmm7, [rsp-8-32]
  and r8, 15
  jnz @move_115
  ret
@move_115:
  add rax, r8
  add rdx, r8
  movups xmm0, [rax - 0*16 - 16]
  movups [rdx - 0*16 - 16], xmm0
  {$ENDIF}
end;

type
  TCall = procedure(const Source; var Dest; Count: NativeInt);

var
  i, g: Integer;

  Str1, Str2: AnsiString;
  StartTime, StopTime: Int64;
  iCounterPerSec: Int64;

procedure Speed(const n: string; c: Pointer; i: Integer);
begin
  QueryPerformanceCounter(StartTime);

  for g := 0 to 10000000 do
  begin
    TCall(c)(Str2[1], Str1[i + 1], Length(Str2) - i);
    TCall(c)(Str2[1], Str1[i + 1], Length(Str2) - i);
    TCall(c)(Str2[1], Str1[i + 1], Length(Str2) - i);
    TCall(c)(Str2[1], Str1[i + 1], Length(Str2) - i);
    TCall(c)(Str2[1], Str1[i + 1], Length(Str2) - i);
    TCall(c)(Str2[1], Str1[i + 1], Length(Str2) - i);
    TCall(c)(Str2[1], Str1[i + 1], Length(Str2) - i);
    TCall(c)(Str2[1], Str1[i + 1], Length(Str2) - i);
    TCall(c)(Str2[1], Str1[i + 1], Length(Str2) - i);
    TCall(c)(Str2[1], Str1[i + 1], Length(Str2) - i);
    TCall(c)(Str2[1], Str1[i + 1], Length(Str2) - i);
    TCall(c)(Str2[1], Str1[i + 1], Length(Str2) - i);
    TCall(c)(Str2[1], Str1[i + 1], Length(Str2) - i);
  end;

  if QueryPerformanceCounter(StopTime) and QueryPerformanceFrequency
    (iCounterPerSec) then
    Writeln(n, ':: ', PrintTime((StopTime - StartTime) / iCounterPerSec));
end;

begin
{$IFNDEF DEBUG}
  Write('Release');
{$ELSE}
  Write('Debug');
{$ENDIF}
{$IF Defined(CPUX64) or Defined(CPUARM64)}
  Writeln(' 64bit');
{$ELSE}
  Writeln(' 32Bit');
{$IFEND}
  System.SetMinimumBlockAlignment(mba16Byte);

  Str1 := 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
    + 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';

  Str2 := '------------------------------------------------------------------------------------------------------------------------------------------------'
    + '------------------------------------------------------------------------------------------------------------------------------------------------';


  i := 9;
  Writeln('-- ', i ,' -- ');
  Speed('MyMove', @MyMove, i);
  Speed('Move', @Move, i);
  Speed('NonCollisionMove', @NonCollisionMove, i);


  i := 0;
  Writeln('-- ', i ,' -- ');
  Speed('MyMove', @MyMove, i);
  Speed('Move', @Move, i);
  Speed('NonCollisionMove', @NonCollisionMove, i);

  i := 3;
  Writeln('-- ', i ,' -- ');
  Speed('MyMove', @MyMove, i);
  Speed('Move', @Move, i);
  Speed('NonCollisionMove', @NonCollisionMove, i);

  Readln;

end.



Результат
Debug 32Bit
-- 9 --
MyMove:: 3.631395
Move:: 9.564001
NonCollisionMove:: 9.057227
-- 0 --
MyMove:: 3.415018
Move:: 5.097708
NonCollisionMove:: 4.003383
-- 3 --
MyMove:: 6.619108
Move:: 9.994631
NonCollisionMove:: 7.615205


Собственно написать этот Move послужило - то, что стандартный Move меняет адрес исходного адреса (Жутко бесила)
...
Рейтинг: 0 / 0
Ну очень быстрый Move() для x86/x64
    #39544657
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Няшик,

@@Move16
Копируешь 8 байт вместо 16
...
Рейтинг: 0 / 0
Ну очень быстрый Move() для x86/x64
    #39544671
Фотография Квейд
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Инструкции REP MOVSx начиная с архитектуры Nehalem, и далее в Ivy Bridge заоптимизированы микрокодом по немогу и по скорости не уступают SSE. Пруф на странице 160.

http://www.cs.utexas.edu/~hunt/class/2017-spring/cs350c/documents/Intel-x86-Docs/64-ia-32-architectures-optimization-manual.pdf
...
Рейтинг: 0 / 0
Ну очень быстрый Move() для x86/x64
    #39545088
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOFT FOR YOUНяшик,
@@Move16
Копируешь 8 байт вместо 16
И в @@Move8 - 4, вместо 8.
Оптимизация-с :)
...
Рейтинг: 0 / 0
Ну очень быстрый Move() для x86/x64
    #39545137
SOFT FOR YOU
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
КвейдИнструкции REP MOVSx начиная с архитектуры Nehalem, и далее в Ivy Bridge заоптимизированы микрокодом по немогу и по скорости не уступают SSE. Пруф на странице 160.

http://www.cs.utexas.edu/~hunt/class/2017-spring/cs350c/documents/Intel-x86-Docs/64-ia-32-architectures-optimization-manual.pdf

Говорят, сейчас на некоторых архитектурах заруливает REP MOVSB
Но мы же тут не для конкретной архитектуры пишем, а в общем, для многих :)
...
Рейтинг: 0 / 0
Ну очень быстрый Move() для x86/x64
    #39545200
Sapersky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Оптимизировали только MOVSB (не SD), т.е. Move от старых Дельфей сам по себе не ускоряется.
Получается, нужно делать отдельную версию Move специально для Ivy Bridge+, проверять процессор и т.д. - слишком муторно.
И на мелких блоках (проверял 256 и 1024 байт с выравниваем 4) SIMD всё равно быстрее.
...
Рейтинг: 0 / 0
Ну очень быстрый Move() для x86/x64
    #39545208
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SaperskyПолучается, нужно делать отдельную версию Move специально для Ivy Bridge+, проверять процессор и т.д.а так оно и делается. на старте детектится камень и подтыкается оптимальная для него версия
...
Рейтинг: 0 / 0
13 сообщений из 38, страница 2 из 2
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Ну очень быстрый Move() для x86/x64
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]