Скажем, у меня есть утверждают() что-то вроде assert(x < limit);
я смотрел на поведение оптимизатора в GDC в выпуске и отладочных сборок со следующим фрагментом кода:утверждают() s, оптимизация и директива предположим() в D
uint cxx1(uint x)
{
assert(x < 10);
return x % 10;
}
uint cxx1a(uint x)
in { assert(x < 10); }
body
{
return x % 10;
}
uint cxx2(uint x)
{
if (!(x < 10))
assert(0);
return x % 10;
}
Теперь, когда я построить в режиме отладки, то утверждает, имеет очень приятный эффект запуска огромных оптимизаций. GDC избавляется от ужасного кода, чтобы полностью выполнить операцию по модулю из-за его знания о возможном диапазоне x из-за условия if-assert. Но в режиме выпуска if-условие отбрасывается, поэтому внезапно возвращается ужасный код, и в cxx1() и даже в cxx1a() больше нет оптимизации. Это очень иронично, что режим освобождения генерирует гораздо худший код, чем код отладки. Конечно, никто не хочет, чтобы исполняемый код, принадлежащий if-tests, присутствовал в коде выпуска, поскольку мы должны потерять все эти накладные расходы.
В идеале я хотел бы выразить это условие в смысле передачи информации компилятору независимо от релизов/отладок, об условиях, которые всегда можно считать истинными, и поэтому такие предположения могут направлять оптимизацию в очень мощные способы.
Я считаю, что некоторые компиляторы C++ имеют нечто, называемое __assume() или некоторые из них, но память мне не помогает. GCC имеет специальную директиву __builtin_unreachable(), которая может быть использована для создания функции accept(). В принципе, если бы я мог построить свою собственную директиву accept(), это могло бы повлиять на утверждение определенных истин о известных значениях или известных диапазонах и публикацию их на пути оптимизации независимо от режима release/отладки, но без создания какого-либо реального кода для accept() в сборке релиза, тогда как в режиме отладки он будет точно таким же, как assert().
Я пробовал эксперимент, который вы видите в cxx2, который всегда оптимизирует оптимизацию, так что там хорошая работа, но он генерирует то, что является морально отладочным кодом для if if-условия accept() даже в режиме выпуска с тестом и условный переход к неопределенной инструкции, чтобы остановить процесс.
Есть ли у кого-нибудь идеи о том, разрешимо ли это? Или вы думаете, что это полезный компилятор F-компилятора?
cxx2 содержит сгенерированный код для if-состояния даже в режиме деблокирования. Цель состоит в том, чтобы пропустить этот код_, как это происходит с кодом проверки состояния в assert. Это то, что я сказал ранее, но, возможно, я не дал понять. –
На самом деле, получить доступ к встроенной встроенной консоли GCC может это сделать, но тогда это полезно только для одного компилятора, но в конце концов, это касается оптимизации. –
Я забыл спросить, как я могу скомпоновать решение cxx2 на что-то опрятное в форме 'accept (cond)', предполагая, что мы не можем сделать ничего лучше. Я понятия не имею, как это сделать без препроцессора, отсутствие опыта работы с D. –