У меня есть gcc
версия 8.2.1
.
В следующем коде я ожидаю, что компилятор не будет генерировать код между двумя mfence
инструкциями в методе CheckAndPrint()
.
Действительно, это хорошо, если я вызываю метод PrintGood<false>()
, а код не генерируется. Но если я прокомментирую PrintBad<false>()
или даже просто return
, компилятор генерирует код для if
-выражения if (t.j > 0)
.
Во всех трех случаях не должно быть причин для создания какого-либо кода, особенно для дорогостоящего ветвления.
Код ниже скомпилирован как:
g++ -std=c++11 -Ofast optimization_problem.cc -o optimization_problem
Пытался напрямую связаться с gcc bugzilla, но у него были проблемы с созданием там учетной записи.
Есть ли веская причина, по которой компилятору удалось оптимизировать код в одном случае, а не в двух других?
#include <iostream>
#include <string>
struct Data {
int i;
int j;
};
template <typename Dummy>
class Test {
public:
template <typename T>
void CheckAndPrint(const T &t);
protected:
template <bool print, typename T>
inline void PrintGood(const std::string &prefix, const T &t);
template <bool print, typename T>
inline void PrintBad(const std::string &prefix, const std::string &postfix, const T &t);
};
template <typename Dummy>
template <typename T>
inline void Test<Dummy>::CheckAndPrint(const T &t) {
asm volatile ("mfence" ::: "memory");
if (t.j > 0) {
//return;
//PrintBad<false>("<", ">", t);
PrintGood<false>("<", t);
}
asm volatile ("mfence" ::: "memory");
}
template <typename Dummy>
template <bool print, typename T>
inline void Test<Dummy>::PrintGood(const std::string &prefix, const T &t) {
if (print)
std::cout << prefix << t.i << t.j << std::endl;
}
template <typename Dummy>
template <bool print, typename T>
inline void Test<Dummy>::PrintBad(const std::string &prefix, const std::string &postfix, const T &t) {
if (print)
std::cout << prefix << t.i << t.j << postfix << std::endl;
}
int main() {
Data data;
std::cin >> data.i;
std::cin >> data.j;
Test<int> t;
t.CheckAndPrint(data);
return 0;
}