// 1.1.1. Метод копирования данных по указателю до 128 Гб.
template< class type1, class type2> // Любые типы.staticvoid Copy( type1* pt1Dest, // Указатель на приёмник данных.const DWORD64 dw64SizeDest, // Размер приёмника данных в байтах.
type2* pt2Source, // Указатель на источник данных.const DWORD64 dw64SizeSource, // Размер источника данных в байтах, начиная от указателя pt2Source.
DWORD64 dw64Count) // Количество копируемых данных в байтах.
{
PBYTE pbtDest = PBYTE(pt1Dest); // Инициализируем локальный указатель на приёмник.
PBYTE pbtSource = PBYTE(pt2Source); // Инициализируем локальный указатель на источник.// Корректируем количество копируемых байт под размер источника.
dw64Count = COUNT_DIRECT(_T( "Utils::Memory::Simple::Copy" ), dw64SizeSource, 0 , dw64Count);
dw64Count = Min(dw64Count, dw64SizeDest);
// Для количества данных более или равно 2147483647 байт цикл необходим.if (dw64Count >= sizeof (BYTES_0X7FFFFFFF))
{
DWORD64 i = 0 ;
DWORD64 dw64Iterations = Utils::Math::Arithmetic::DivideFloor(dw64Count, sizeof (BYTES_0X7FFFFFFF)); // Количество итераций. Округляем в меньшую сторону.
START: if (!SimpleCopy<BYTES_0X7FFFFFFF>(pbtDest, pbtSource, dw64Count)) return ;
i++;
if (i < dw64Iterations) goto START;
}
if (!SimpleCopy<BYTES_0X40000000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X20000000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X10000000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X8000000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X4000000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X2000000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X1000000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X800000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X400000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X200000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X100000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X80000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X40000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X20000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X10000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X8000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X4000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X2000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X1000>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X800>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X400>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X200>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X100>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X80>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X40>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X20>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X10>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X8>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X4>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X2>(pbtDest, pbtSource, dw64Count)) return ;
if (!SimpleCopy<BYTES_0X1>(pbtDest, pbtSource, dw64Count)) return ;
}
추가 주기를 없애려고 했습니다. 이 코드는 표준 memcpy 보다 20% 빠릅니다. 또한 복사 크기 제한이 없으며 memcpy보다 안전합니다.
모든 for는 해당하는 while로 대체될 수 있으며 그 반대의 경우도 마찬가지입니다. 그리고 이러한 디자인 중 어느 것이 다른 디자인보다 분명히 더 경제적일 가능성은 거의 없습니다.
예, 바딤 ? asm은 필요없으니 C로 해보자.
고맙습니다. 내가 이해하는 한 더 빨리 작동해야 하는 주요 구성은 다음과 같습니다.
글쎄, 이것은 동안 에뮬레이션입니다. 네, 표준 주기보다 빠르다는 점은 충분히 인정합니다. 그러나 아마도 제어 구조 자체를 초기화하는 데 시간이 덜 걸리기 때문일 것입니다.
그리고 이 "주기"에서 얼마나 많은 반복을 수행합니까?
조금 더 빠릅니다.
이런 :)
예, 그렇습니다. 어셈블러에는 jmp도 있습니다. 그래서 무엇을 위해 만들어졌습니까?
goto는 예외가 없는 훌륭한 대안이지만 finally 블록과 같은 것이 필요합니다.
물론 if로 잘 풀릴 수 있지만 goto는 아마도 훨씬 더 우아할 것입니다.
그러나 일반적으로 일반 포크가 있으면 이쑤시개로 스파게티를 먹는 것이 합리적입니다.
그리고 코드에서 당신을 뒤따르는 프로그래머는 머리를 쓰다듬지 않을 것입니다.