2017-02-05 6 views
0

У меня очень странная проблема с компилятором GCC (G ++). Мой код на C++ показан ниже.-O2 оптимизация не выходит из цикла при чтении большого файла

int main() { 
    ifstream ifsr("some-large-file.bin", ios::binary | ios::in); 
    for (int i = 0; i < 50000; i++) { 
     ifsr.seekg(60000 * i); 
     if (i % 1000 == 0) cout << i << "\n"; 
    } 
    ifsr.close(); 
    return 0; 
} 

Должно остановиться после i >= 50000. Однако, если я скомпилировал код с использованием опций -O2 или -O3, цикл не останавливается (он продолжает итерацию, даже когда i > 50000). Он хорошо работает, если я скомпилировал его, используя опцию -O. И если я прокомментировал линию ifsr.seekg(60000 * i);, это также хорошо работает (даже с параметрами -O2 и -O3). Я также проверил код в моем экземпляре AWS (EC2 c3.2xlarge с Ubuntu 16.42), и он показывает аналогичное поведение. (Я использую bash для Windows 10).

Я понятия не имею, что на самом деле происходит в этом коде. И если есть решение запустить аналогичный код, не отбрасывая -O2 или -O3 вариантов, это было бы здорово! Спасибо.

+0

Я не знаю, пытаетесь ли вы оптимизировать скорость чтения/чтения файлов, но если вы оптимизатор компилятора, вероятно, не поможет. –

+0

Этот код является лишь частью более крупных кодов (которые не показаны для простоты). Я использую оптимизацию компилятора для оптимизации других частей кода. – Firman

ответ

4

49999*60000 = 2,999,940,000 переполняет обычно 32-разрядную подпись int. Это неопределенное поведение и должно быть корнем проблемы.

Например, оптимизатору разрешено считать, что i никогда не превышает (2^31 - 1)/60000, поскольку он может считать, что UB никогда не происходит, и по этой логике условие цикла всегда истинно. (Может или не может быть точно что происходит, UB может ломать вещи разными способами.)

Вместо этого используйте int64_t i.

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

  • Нет связанных вопросов^_^