Как предотвратить векторную оптимизацию работы этой функции с помощью компилятора arm-none-eabi-gcc?

Мой код

Я работаю с простым кодом, который использует эту функцию в академическом проекте:

void calculateDistanceMatrix(const float data[M][N],
                             float distance[M][N]) {
    float sum = 0.0;
    for(int i = 0; i < M; i++) {
        for(int j = i+1; j < M; j++) {
            for(int k = 0; k < N; w++) {
                sum += (data[i][k] - data[j][k]) *
                       (data[i][k] - data[j][k]);
            }
            distance[i][j] = sum;
            distance[j][i] = sum;
            distance[i][i] = 0.0;
            sum = 0.0;
        }
    }
}

Моя целевая архитектура

Мой код должен выполнять не более чем эту простую матричную операцию над "данными" и заполнять матрицу "расстояний" результатами. Однако в моем академическом проекте меня интересует, как компилятор оптимизирует эти векторные операции для архитектуры ARM, с которой я работаю. Командная строка для компиляции содержит следующее:

arm-none-eabi-gcc <flags> <my_sources> -mcpu=cortex-a9 -mfpu=vfpv3 -mfloat-abi=hard <more_flags>

Моя программа предназначена для запуска на встроенном устройстве Xilinx Zynq-7000, архитектура которого включает оптимизированный набор NEON для векторных операций (описан в этой хорошей презентации)

Моя проблема

Я должен отслеживать производительность выполнения векторных операций в функции "CalculateDatMatrix" с оптимизацией компилятора и без него. Я заметил, что вывод сборки включает в себя общие инструкции NEON и VFP для векторной загрузки и операций хранения (подробно описано в справочнике по ассемблеру ARM для версии 5.0):

ecf37a01    vldmia  r3!, {s15}
ecf26a01    vldmia  r2!, {s13}
e1530000    cmp r3, r0
ee777ae6    vsub.f32    s15, s15, s13
ee077aa7    vmla.f32    s14, s15, s15
1afffff9    bne 68 <calculateDistanceMatrix+0x48>
eca17a01    vstmia  r1!, {s14}

Я не смог найти способ скомпилировать этот код так, чтобы эти оптимизированные инструкции не использовались.

Знаете ли вы какую-либо конфигурацию компиляции или хитрость кода, которая могла бы избежать этих инструкций? Ценю любую помощь по этому вопросу.

2 ответа

Я вернулся к этой проблеме и обнаружил, что моя среда была настроена на сборку в режиме отладки, поэтому никакой оптимизации не было.

Фактически оптимизированный код использует инструкции VLDM и VSTM. Они не генерируются, однако, когда я добавляю прагму

#pragma GCC optimize ("O0")

в моем исходном файле.

Приведенные вами инструкции не являются векторными операциями:vsub.f32 s15, s13, s15Это простое 32-битное вычитание с плавающей точкой. Вы можете сказать, используя 32-битную форму S-регистра и .f32 суффикс в инструкции

Другие вопросы по тегам