2013-05-25 33 views
6

Tôi sắp viết một mô phỏng tổng hợp khuếch tán giới hạn mạng (DLA) và tôi tự hỏi có nên sử dụng C hoặc C++ hay không.C so với C++ để mô phỏng số (hiệu suất)

C++ sẽ rất hay vì lý do thiết kế nhưng tôi tự hỏi liệu C có hoạt động tốt hơn không. Tất nhiên tôi biết về hiệu suất thuật toán và đã chọn thuật toán tốt nhất có thể. Vì vậy, tôi không nói về việc cải thiện O (n^2) thành O (log n) hoặc tương tự. Tôi đang cố gắng giảm các hằng số của mình để nói.

Nếu bạn không biết DLA, về cơ bản nó sẽ có một chuỗi đôi (kích thước từ 10^3 đến 10^6) và trong vòng lặp chọn ngẫu nhiên tăng gấp đôi để so sánh (lớn hơn/ít hơn) với phần lớn mảng.

Vì vậy, sự khác biệt hiệu suất mà sẽ có vấn đề của việc này là truy cập dữ liệu và chức năng gọi số:

  • truy cập dữ liệu: C struct vs lớp C++ với các thành viên dữ liệu công cộng vs ++ lớp C với các thành viên dữ liệu cá nhân và bộ truy xuất.
  • Chức năng gọi: C chức năng so với chức năng thành viên C++.

Tôi có quyền kết luận rằng cách cuối cùng để đánh giá điều này là xem mã lắp ráp (ví dụ: so sánh số lượng di chuyển/tải, nhảy và cuộc gọi)? Điều này tất nhiên là phụ thuộc vào trình biên dịch (ví dụ: bạn có thể so sánh trình biên dịch C khủng khiếp với trình biên dịch C++ tốt). Tôi đang sử dụng trình biên dịch Gnu (gcc và g ++).

Tôi đã phát hiện ra rằng việc lắp ráp sản xuất bởi gcc và g ++ là gần như giống hệt nhau về mặt số lượng nhảy (không có), di chuyển/tải và kêu gọi hai chương trình sau:

chương trình C

#include <stdlib.h> 

typedef struct 
{ 
    double x; 
} particle; 

double square(double a) 
{ 
    return a*a; 
} 

int main() 
{ 

    particle* particles = malloc(10*sizeof(particle)); 
    double res; 

    particles[0].x = 60.42; 

    res = square(particles[0].x); 

    return 0; 
} 

C++ chương trình

class particle 
{ 
    public: 
     double x; 

    public: 
     double square() 
     { 
      return x*x; 
     } 

}; 

int main() 
{ 

    particle* particles = new particle[10]; 
    double res; 

    particles[0].x = 60.42; 

    res = particles[0].square(); 

    return 0; 
} 

Nếu tôi sử dụng tôi tin dữ liệu mber trong chương trình C++ tôi dĩ nhiên nhận được một cuộc gọi khác trong assembly khi tôi gọi các hạt [0] .setx (60.42).

Điều này có nghĩa là tôi cũng có thể chọn C++ là C vì chúng sản xuất gần như cùng một mã assembly? Tôi có nên tránh dữ liệu thành viên riêng tư vì nó cho biết thêm các cuộc gọi chức năng bổ sung (ví dụ: cuộc gọi trong lắp ráp có đắt không)?

+1

C++ giống như và có thể hoạt động hiệu quả hơn C. Bạn gọi g ++ như thế nào? Tôi rất ngạc nhiên khi nó không nằm trong phương thức 'square()' nếu chúng ở trên – Collin

+0

Không có điểm nào tạo ra phương thức 'setx' nếu điều duy nhất nó làm là thiết lập x thành bất cứ thứ gì được truyền vào trong bạn cũng có thể làm dữ liệu công khai. Cũng sử dụng C++ không có nghĩa là bạn không thể sử dụng cấu trúc chỉ với các thành viên. –

+0

Nếu thuật toán của bạn phụ thuộc vào mảng lớn các số, bạn có thể muốn tránh sử dụng các lớp có biến thành viên như trong ví dụ của bạn vì cách lớp được đặt trong bộ nhớ. Bạn có thể thấy hiệu suất tốt hơn với phân bổ tăng gấp đôi liên tục lớn thay vì phân bổ liên tục các lớp với dữ liệu thành viên hỗn hợp. – PureW

Trả lời

8

Với những thứ bạn phác thảo, tôi sẽ ngạc nhiên khi thấy một lợi thế đáng kể đối với C cho bất kỳ thứ gì trong số đó. Dựa trên những gì bạn đã nói, tôi cũng đoán so sánh (s) bạn đã làm được dựa trên biên dịch với ít hoặc không có tối ưu hóa được kích hoạt. Với tối ưu hóa đầy đủ được kích hoạt, tôi mong đợi ngay cả những người biến mất.

Về lâu dài, C++ cung cấp nhiều cơ hội hơn cho việc tối ưu hóa. Một trong số đó khá phổ biến với số học ma trận (mặc dù tôi không chắc nó có thể áp dụng cho mô phỏng DLA của bạn) là các mẫu biểu thức, mà bạn có thể sử dụng để "làm phẳng" tính toán để tránh sao chép dữ liệu nếu cần.

Tóm lại: C++ sẽ kết thúc chính xác tương đương với C (nghĩa là, trong trường hợp xấu nhất, bạn sẽ viết mã C++ của bạn hầu như giống như mã C và không thấy sự khác biệt về hiệu suất). Tốt nhất, các tính năng bổ sung của C++ (đặc biệt là các mẫu) cung cấp cho bạn cơ hội để tối ưu hóa theo những cách không thể hoặc không thực tế với C.

+0

Không biết về 'lập trình meta mẫu'. Cám ơn vì cái này. –

+0

Bạn nói đúng, tôi đã làm bài kiểm tra này mà không có bất kỳ cờ tối ưu nào được chuyển tới trình biên dịch Gnu. Việc lắp ráp O2 và O3 gần như không thể đọc được. – Wuhtzu

+0

@Wuhtzu: Vâng - với tối ưu hóa được bật, kết quả có thể khá lông. * Thông thường * khá nhanh mặc dù. –

1

Trong trường hợp bạn đã đăng, về cơ bản bạn yêu cầu sự khác biệt hiệu suất giữa mallocnew.

Trong C++, toán tử new thực hiện chức năng bổ sung, chẳng hạn như gọi hàm tạo của đối tượng hoặc khởi tạo biến.

Đối với hoạt động tương đương trong C, bạn cần phải khởi tạo biến sau khi gọi malloc. Thay đổi chương trình C của bạn để hoạt động giống như C++ sau đó là profile.

Trong hầu hết các câu hỏi về hiệu suất, bạn cần phải so sánh táo với táo. Nếu bạn sử dụng Lập trình hướng đối tượng trong C++, bạn sẽ cần mã tương đương trong C++ trước khi thực hiện so sánh. Với điều này, trong hầu hết các trường hợp, không có sự khác biệt không đáng kể về hiệu suất giữa hai ngôn ngữ.

Đồng thời xem xét: thời gian phát triển, tính chính xác, mạnh mẽ, an toàn và sự tự tin hoặc trải nghiệm của bạn với ngôn ngữ. Hiệu suất thường không đáng kể khi so sánh với các thuộc tính khác của dự án.

Nhiều vấn đề về hiệu suất không phụ thuộc vào ngôn ngữ mà là thiết kế và nền tảng. Xóa bộ nhớ cache, bỏ vòng lặp, nhiều so sánh, tất cả có thể ảnh hưởng đến hiệu suất bất kể ngôn ngữ.

+0

Điểm tốt. Tôi đã không lo lắng về việc mới so với malloc. Tôi đã lo lắng rằng có thể có một chi phí trong việc thu thập dữ liệu thành viên của một lớp comparted dữ liệu được lưu trữ trong cấu trúc hoặc dữ liệu được lưu trữ trực tiếp trong một mảng. Trước khi tôi nhìn vào lắp ráp tạo ra từ C + + lấy dữ liệu thành viên tôi sợ nó có thể liên quan đến một số nhảy vv mà sẽ làm cho nó ít hoạt động so với các truy cập dữ liệu khác. Nhưng nó quay ra gần như cùng một mã assembly nên tôi cho rằng nó tương đương về hiệu năng. Tôi chưa bao giờ viết một trình biên dịch cho một ngôn ngữ hướng đối tượng. – Wuhtzu

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