Могут ли компиляторы вообще объединять несколько смежных копий памяти в одну операцию?

Что-то вроде следующего:

struct Vec2
{
int x, y;
};

struct Bounds
{
int left, top, right, bottom;
};

int main()
{
Vec2 topLeft = {5, 5};
Vec2 bottomRight = { 10, 10 };
Bounds bounds;
//___Here is copy operation
//___Note they're not in contiguous order, harder for the compiler?
bounds.left = topLeft.x;
bounds.bottom = bottomRight.y;
bounds.top = topLeft.y;
bounds.right = bottomRight.x;
}

Эти четыре задания можно сделать так:

memcpy(&bounds, &topLeft, sizeof(Vec2));
memcpy(&bounds.right, &bottomRight, sizeof(Vec2));

Мне интересно две вещи:

  1. Могут ли компиляторы обычно оптимизировать таким образом?
  2. Четыре копии int совпадают с двумя копиями пары int, поскольку память для копирования равна O (n)?

Я получил следующие результаты разборки для четырех копий:

bounds.left = topLeft.x;
00007FF642291034  mov         dword ptr [bounds],5
bounds.bottom = bottomRight.y;
00007FF64229103C  mov         dword ptr [rsp+2Ch],0Ah
bounds.top = topLeft.y;
00007FF642291044  mov         dword ptr [rsp+24h],5
bounds.right = bottomRight.x;
00007FF64229104C  mov         dword ptr [rsp+28h],0Ah

И, как ни странно, два memcpys — это разные инструкции для первого и второго, я не понимаю этого:

memcpy(&bounds, &topLeft, sizeof(Vec2));
00007FF64229105E  mov         rbx,qword ptr [topLeft]   // This is only one instruction
memcpy(&bounds.right, &bottomRight, sizeof(Vec2));
00007FF642291063  mov         rdi,qword ptr [bottomRight]  // Compared to 6?
00007FF642291068  mov         qword ptr [bounds],rbx
00007FF64229106D  mov         qword ptr [rsp+28h],rdi
00007FF642291072  jmp         main+7Eh (07FF64229107Eh)
00007FF642291074  mov         rdi,qword ptr [rsp+28h]
00007FF642291079  mov         rbx,qword ptr [bounds]

0

Решение

Любой современный компилятор, поддерживающий потоки, должен учитывать зависимости команд и переупорядочение. С этой технологией она быстро обнаружит, что в наборе инструкций нет зависимостей, что означает, что они могут быть переупорядочены в линейном порядке памяти, а затем объединены.

Не то чтобы это, вероятно, имеет значение; кэш ЦП просто загрузит всю строку кеша при первом доступе и очистит всю строку кеша в более поздний момент. Эти операции занимают время, а не сами операции процессора.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector