Я пытаюсь узнать больше об ARM-сборке и понять, что именно происходит за кулисами с NEON intrinsics. Я использую последний компилятор Xcode LLVM. Я нахожу, что часто сборка, созданная из встроенных функций, на самом деле медленнее, чем даже простой наивный код C.Сборка, созданная с помощью NEON intrinsics [LLVM - Xcode]
Например, этот код:
void ArmTest::runTest()
{
const float vector[4] = {1,2,3,4};
float result[4];
float32x4_t vA = vld1q_f32(vector);
asm("#Begin Test");
vA = vmulq_f32(vA, vA);
asm("#End Test");
vst1q_f32(result, vA);
}
Производит этот вывод:
#Begin Test
ldr q0, [sp, #16]
stp q0, q0, [fp, #-48]
ldur q1, [fp, #-32]
fmul.4s v0, v1, v0
str q0, [sp, #16]
#End Test
То, что я не понимаю, почему все грузы/магазины ударяя память здесь? Я должен упустить что-то очевидное, не так ли? Кроме того, как бы написать это в встроенной сборке, чтобы она была оптимальной? Я бы ожидал только одной инструкции, но результат был другим.
Пожалуйста, помогите мне разобраться.
Спасибо!
Вы никогда не должны доверия компиляторы. Глядя на ваш пример, особенно 64-битные коды намного далеки от полных приличных. Перестаньте тратить время на внутреннюю проверку и проверку сгенерированных кодов, но вместо этого изучайте сборку. В любом случае вы не получите очень далеко от внутренних функций, не зная реальных инструкций. –
Вы также должны знать, что доступ к одной и той же области памяти с ARM и NEON отнимает много циклов при «переключении». Поэтому, если вы пишете тестовые функции, вы должны позволить им обрабатывать большой фрагмент данных с помощью нескольких итераций. В вашем примере вектор, вероятно, инициализируется ARM в стеке и считывается и вычисляется NEON - очень медленно. –
void square (float * pDst, float * pSrc, unsigned int size); <== например. –