2015-11-21 26 views
6

Tôi tóm tắt vấn đề của mình cho chương trình ngắn sau đây.SEGFAULT ở chế độ -O3?

Nó chỉ gây SEGFAULT ở chế độ -O3 (-O2 hoạt động tốt). Theo số gdb, điều này xảy ra tại số *f = 0.

#include <iostream> 

void func1(int s, int t) 
{ 
     char* buffer = new char[s + t*sizeof(float)]; 
     if (!buffer) 
     { 
      std::cout << "new failed\n"; 
      return; 
     } 
     float* f = (float*)(buffer + s); 
     for (int i = 0; i < t; ++i) 
     { 
      *f = 0; 
      //std::cout << i << std::endl; // if uncomment this line everything will work fine 
      ++f; 
     } 
     delete [] buffer; 
     std::cout << "done\n"; 
} 

int main() 
{ 
     int s = 31, t = 12423138; 
     std::cout << s << " " << t << std::endl; 
     func1(s, t); 
     return 0; 
} 

Vui lòng cho tôi biết, tôi đang làm gì sai?

+8

Đó là một vi phạm trắng trợn của [sự cai trị răng cưa chặt chẽ] (http : //stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule). Đối với vụ tai nạn có thể là do bạn truy cập dữ liệu chưa được ký. Do vấn đề bí danh, điều này có thể không hữu ích, nhưng hãy cố gắng biên dịch với nhiều cảnh báo hơn (ví dụ: '-Wall -Wextra -pedantic') và xem liệu nó có nói cho bạn điều gì không. –

+0

@JoachimPileborg Tôi biên soạn mã này trên MSVC với -W4 -Wx, và nó được biên dịch tốt. –

+1

AFAIK MSVC++ không bao giờ giả định các quy tắc bí danh nghiêm ngặt và không thực hiện bất kỳ sự tối ưu nào phụ thuộc vào các quy tắc này. –

Trả lời

2

Nguồn SEGFAULT không chỉ vi phạm quy tắc bí danh nghiêm ngặt, vì sự cố vẫn tiếp diễn ngay cả với cờ -giảm bí mật nghiêm ngặt.

Nó thực sự truy cập bộ nhớ chưa được ký, nhưng không đơn giản như vậy. Là bộ vi xử lý hiện đại, thường cho phép truy cập bộ nhớ không được ký hiệu và thậm chí không có nhiều chi phí cho ngày nay. Tôi đã thực hiện một số điểm chuẩn và không quan sát thấy một sự khác biệt lớn trong algined vs unaligned đọc trên Intel của tôi (R) Xeon (R) CPU E5-2680 v2 @ 2.80GHz. Ngoài ra có some kết quả rất giống nhau (và nhiều hơn hoặc ít hơn gần đây) trên web.

Vấn đề của tôi là chế độ -O3 cho phép cờ -ftree-vectorize, do đó chu kỳ for của chúng tôi được vector hóa (như tôi có thể thấy sử dụng cờ -ftree-vectorizer-verbose). Và (AFAIU) không có hỗ trợ (chưa?) Cho truy cập bộ nhớ không được ký hiệu bằng cách sử dụng các hướng dẫn vectorized, do đó, có một ngoại lệ thời gian chạy.

This article giúp tôi rất nhiều trong việc tìm hiểu lý thuyết, mặc dù có vẻ như truy cập hiện nay bộ nhớ unaligned không phải là có hại vì nó là, mặc dù vẫn còn khó khăn

Các vấn đề liên quan