Tại sao một nhà khoa học tính toán cần phải thực hiện phiên bản std :: phức tạp của riêng họ?


14

Nhiều thư viện C ++ nổi tiếng trong khoa học tính toán như Eigen , Trilinosdeal.II sử dụng đối tượng thư viện tiêu đề mẫu C ++ tiêu chuẩn std::complex<>, để biểu diễn các số dấu phẩy động phức tạp.

Trong Jack Poulson của câu trả lời cho một câu hỏi về nhà xây dựng mặc định, ông chỉ ra rằng ông có thực hiện của riêng mình của std::complextrong Elemental "đối với một số lý do". Những lý do đó là gì? Những lợi thế và bất lợi của phương pháp này là gì?

Câu trả lời:


16

Tôi tin rằng cuộc thảo luận này đã đưa ra một số lần trong danh sách PETSc. Lý do chính của tôi là:

  1. Tiêu chuẩn C ++ nói rằng std :: phức tạp chỉ được xác định cho các kiểu dữ liệu float, double và double. Do đó, nó không thể được sử dụng cho các kiểu dữ liệu khác, chẳng hạn như độ chính xác bốn.

  2. Tiêu chuẩn này không đảm bảo về tính ổn định của số học phức tạp.

  3. Tiêu chuẩn không đảm bảo rằng dữ liệu trong một phức std :: được lưu trữ dưới dạng thành phần thực theo sau là thành phần tưởng tượng. Điều này rất quan trọng đối với các giao diện với các thư viện bên ngoài, chẳng hạn như BLAS và LAPACK. Điều này đúng với tất cả các triển khai chính, nhưng tôi muốn có thể đảm bảo nó.

  4. Tôi thích có thể trực tiếp thao tác các thành phần thực và tưởng tượng. std :: phức tạp làm cho điều này khó khăn không cần thiết.

  5. Cuối cùng tôi muốn có một phiên bản tổng quát hơn, chỉ yêu cầu kiểu dữ liệu là một vòng thay vì yêu cầu một trường. Điều này sẽ bao gồm các số nguyên Gaussian.


6
Điểm 3 đã được giải quyết trong C ++ 11. 26.4.4 bang rằng nếu zlà một biểu thức vế trái của loại cv std::complex<T> sau đó reinterpret_cast<cv T(&)[2]>(z)reinterpret_cast<cv T(&)[2]>(z)[0]sẽ chỉ định một phần thực sự của z, và reinterpret_cast<cv T(&)[2]>(z)[1]sẽ chỉ định phần ảo của z. Mảng số phức cũng được giải quyết.
James Custer

3
@JamesCuster: Cuối cùng tôi cũng chuyển sang C ++ 11, nhưng các mã khoa học muốn duy trì tính di động cho các kiến ​​trúc bán kỳ lạ có lẽ sẽ phải chờ ít nhất hai đến ba năm nữa để làm điều đó. Ngoài ra, C ++ 11 không may chỉ giải quyết một phần của vấn đề.
Jack Poulson

Tôi hiểu, tôi chỉ ném nó ra ngoài trong trường hợp ai đó nhìn vào câu hỏi này trong tương lai.
James Custer

2
Chà, tôi nghĩ đó là một cảnh sát để nói rằng bạn phải đợi cho đến khi trình biên dịch hỗ trợ C ++ 11. Yêu cầu rõ ràng đã được đưa vào tiêu chuẩn mới bởi vì tất cả các triển khai hiện có đã hỗ trợ nó. Tôi không thể nghĩ đến trường hợp sẽ không an toàn khi giả định bố cục cụ thể này trong các trình biên dịch / thư viện hiện tại vì đơn giản là nó sẽ không có ý nghĩa gì khi thực hiện std :: phức tạp theo bất kỳ cách nào khác.
Wolfgang Bangerth

1
@WolfgangBangerth: Đó là một nhận xét chung về việc chuyển sang C ++ 11. Dù bằng cách nào, C ++ 11 không khắc phục được hầu hết các vấn đề với std :: phức tạp.
Jack Poulson

7

Tôi sử dụng std::complex<>trong các chương trình của mình và phải chiến đấu với cờ trình biên dịch và cách khắc phục cho mỗi trình biên dịch hoặc trình biên dịch mới. Tôi sẽ cố gắng kể lại những trận đánh này theo thứ tự thời gian:

  1. std::norm|z|2|z|-ffast-math
  2. Trình biên dịch intel icc trên linux (hoặc trình liên kết) được biên dịch std::argthành không chọn theo các cấu hình nhất định (tương thích liên kết với một phiên bản gcc cụ thể). Vấn đề xuất hiện trở lại quá thường xuyên, do đó std::argphải được thay thế bằng atan2(imag(),real()). Nhưng tất cả quá dễ dàng để quên điều này khi viết mã mới.
  3. Loại std::complexsử dụng các quy ước cuộc gọi khác nhau (= ABI) so với loại phức hợp C99 tích hợp và loại phức hợp Fortran tích hợp cho các phiên bản gcc mới hơn.
  4. Các -ffast-mathtương tác cờ biên dịch với việc xử lý các trường hợp ngoại lệ điểm nổi theo những cách bất ngờ. Điều gì xảy ra là trình biên dịch kéo các bộ phận ra khỏi các vòng lặp, do đó gây ra division by zerongoại lệ khi chạy. Những ngoại lệ này sẽ không bao giờ xảy ra trong vòng lặp, bởi vì sự phân chia tương ứng đã không diễn ra do logic xung quanh. Đó là một điều thực sự tồi tệ, bởi vì đó là một thư viện được biên dịch tách biệt với chương trình sử dụng xử lý ngoại lệ dấu phẩy động (sử dụng các cờ biên dịch khác nhau) và gặp phải các vấn đề này (các đội tương ứng đang ngồi ở các khu vực đối diện trên thế giới, vì vậy vấn đề này thực sự gây ra rắc rối xấu). Điều này đã được giải quyết bằng cách thực hiện tối ưu hóa được sử dụng bởi trình biên dịch bằng tay cẩn thận hơn.
  5. Thư viện đã trở thành một phần của chương trình và không còn sử dụng -ffast-mathcờ biên dịch. Sau khi nâng cấp lên phiên bản gcc mới hơn, hiệu suất giảm do yếu tố rất lớn. Tôi đã không điều tra vấn đề này một cách chi tiết, nhưng tôi sợ nó có liên quan đến C99 Phụ lục G . Tôi phải thừa nhận rằng tôi hoàn toàn bối rối với định nghĩa nhân số kỳ lạ này cho các số phức và thậm chí dường như còn tồn tại các phiên bản khác nhau của điều này với tuyên bố rằng các phiên bản khác bị nhầm lẫn. Tôi hy vọng rằng -fcx-limited-rangecờ biên dịch sẽ giải quyết vấn đề, bởi vì dường như có một vấn đề khác liên quan đến -ffast-mathphiên bản gcc mới hơn này.
  6. Các -ffast-mathlá cờ biên dịch làm cho hành vi của NaNhoàn toàn không thể đoán trước cho các phiên bản mới hơn của gcc (thậm chí isnanbị ảnh hưởng). Cách giải quyết duy nhất dường như là để tránh mọi sự xuất hiện NaNtrong chương trình, đánh bại mục đích cho sự tồn tại của NaN.

Bây giờ bạn có thể hỏi liệu tôi có kế hoạch từ bỏ các loại phức tạp tích hợp không và std::complexvì những lý do này. Tôi sẽ ở lại với các loại tích hợp, miễn là tôi ở lại với C ++. Trong trường hợp C ++ nên quản lý để trở nên hoàn toàn không sử dụng được cho máy tính khoa học, tôi muốn xem xét chuyển sang một ngôn ngữ quan tâm nhiều hơn đến các vấn đề liên quan đến điện toán khoa học.


Có vẻ như nỗi sợ hãi của tôi liên quan đến C99 Phụ lục G đã trở thành sự thật và phạm vi giới hạn -fcx hiện là loại yêu cầu cho tốc độ tính toán hợp lý khi nhân các số phức. Ít nhất đó là những gì tôi nhận được từ câu chuyện chiến tranh gần đây: Medium.com/@smcallis_71148/ Khăn
Thomas Klimpel
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.