У меня есть простая программа, которая сначала записывает некоторые собственные инструкции x86 в объявленный буфер, а затем устанавливает указатель функции на этот буфер и выполняет вызов. Однако я замечаю серьезное снижение производительности, когда этот буфер выделяется в стеке (а не в куче или даже в области глобальных данных). Я проверил, что начало последовательности команд в буфере данных находится на 16-байтовой границе (я предполагаю, что это то, что процессор требует (или хочет), чтобы это было). Я не знаю, почему будет иметь значение, где я выполняю свои инструкции в процессе, но в приведенной ниже программе «ХОРОШО» выполняется на моей двухъядерной рабочей станции за 4 секунды, а «ПЛОХО» - около 6 минут , Есть ли здесь какая-то проблема с выравниванием / i-cache / предсказанием? Моя оценочная лицензия на VTune только что закончилась, поэтому я даже не могу провести анализ по этому вопросу :(. Спасибо.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
typedef int (*funcPtrType)(int, int);
int foo(int a, int b) { return a + b; }
void main()
{
// Instructions in buf are identical to what the compiler generated for "foo".
char buf[201] = {0x55,
0x8b, 0xec,
0x8b, 0x45, 0x08,
0x03, 0x45, 0x0c,
0x5D,
0xc3
};
int i;
funcPtrType ptr;
#ifdef GOOD
char* heapBuf = (char*)malloc(200);
printf("Addr of heap buf: %x\n", &heapBuf[0]);
memcpy(heapBuf, buf, 200);
ptr = (funcPtrType)(&heapBuf[0]);
#else // BAD
printf("Addr of local buf: %x\n", &buf[0]);
ptr = (funcPtrType)(&buf[0]);
#endif
for (i=0; i < 1000000000; i++)
ptr(1,2);
}
Результаты выполнения этого:
$ cl -DGOOD ne3.cpp
32-разрядный оптимизирующий компилятор C / C ++ Microsoft (R) версии 11.00.7022 для 80x86
Copyright (C) Microsoft Corp 1984-1997. Все права защищены.
ne3.cpp
32-разрядный инкрементальный компоновщик Microsoft (R) версии 5.10.7303
Авторские права (C) Microsoft Corp 1992-1997. Все права защищены.
/ выход: ne3.exe
ne3.obj
$ time ./ne3
Адрес кучи buf: 410eb0
реальный 0 м 4,33 с
пользователь 0m 4.31s
sys 0m 0,01 с
$
$
$ cl ne3.cpp
32-разрядный оптимизирующий компилятор C / C ++ Microsoft (R) версии 11.00.7022 для 80x86
Copyright (C) Microsoft Corp 1984-1997. Все права защищены.
ne3.cpp
32-разрядный инкрементальный компоновщик Microsoft (R) версии 5.10.7303
Авторские права (C) Microsoft Corp 1992-1997. Все права защищены.
/ выход: ne3.exe
ne3.obj
$ time ./ne3
Адрес локального буфера: 12feb0
реально 6м41.19с
пользователь 6m40.46s
sys 0m 0,03 с
$
Спасибо.