2016-03-25 1 views
1

я обнаружил, что in Linux kernel, the clflush function реализуется какПочему clflush потребности + м постоянной

asm volatile("clflush %0" : "+m" (*(volatile char __force *)__p)); 

Я не совсем понимаю, почему + м используется здесь?

В моем понимании, она не должна быть реализована в виде

asm volatile ("clflush (%0)" :: "r"(p)); 
+1

В любом случае, очевидным способом его написания будет 'asm volatile (" clflush% 0 "::" m "(* (char *) p))'. Нет необходимости принуждать компилятор использовать простой режим адресации (% reg) без смещения или индекса. ** Удивительная и интересная часть - это '+', а не 'm' **. –

ответ

2

Либо форма обучения работает, так как они оба относятся к одному адресу. Однако, используя +m в качестве ограничения, он гарантирует, что любая оптимизация, выполняемая с кодом (поскольку функция является встроенной), не предполагает сохранение данных, хранящихся в указателе __p. Другими словами, он предотвращает недопустимую оптимизацию.

+1

Или иначе: он (пытается) убедиться, что компилятор не имеет части кешированной строки, все еще хранящейся в регистрах. Это может привести к поражению цели флеша, если самая следующая инструкция записала регистр в строку кэша. –

+0

Я вижу. Это заставляет компилятор перезагружать контент вместо повторного использования содержимого, созданного в кеше. – Mike

+0

Без '+', я думаю, вам понадобится '' memory ''clobber, что было бы хуже для оптимизатора. Возможно, объявление его в качестве операнда памяти только для ввода будет работать, но использование операнда ввода/вывода более безопасно, потому что оно заставляет компилятор рассматривать его как часть цепочки зависимостей с использованием этой памяти. 'asm volatile' не всегда может быть достаточным, чтобы избежать переупорядочения. –

Смежные вопросы