2015-06-06 16 views
27
time javac Main.java          --> 0m1.050s 
time javac Main.java & javac Main.java     --> 0m1.808s 
time javac Main.java & javac Main.java & javac Main.java --> 0m2.690s 
time javac Main.java & ... 8 time       --> 0m8.309s 

Khi chúng tôi chạy javac lệnh song song và với mỗi gia tăng javac lệnh ~1 sec được thêm vào cho tất cả các javac lệnh để hoàn thành.thực hiện tại sao song song trên java biên dịch lấy tăng trưởng tuyến tính trong thời gian

Tại sao có tăng trưởng tuyến tính là thời gian?

Là tất cả javac quá trình trong khi chạy tham gia vào một số loại trên locks, nếu có làm thế nào để vượt qua nó như vậy là không có một sự phát triển tuyến tính trong thời gian


PS: Tôi đã thử trên trên single core machine, double core machine, 4 core machine tất cả đều hiển thị cùng một hành vi.

PS2: môi trường RedHat7, javac 1.7.0_79

+2

Có thể dễ dàng là I/O-bound, không bị ràng buộc CPU. –

+1

bất kỳ ý tưởng nào về cách xác nhận nếu io của nó bị ràng buộc ... trông giống như vậy vì dữ liệu của chúng tôi rất nhỏ – Bhuvan

+0

Hmmm, 'javac' muốn tệp. Tôi đoán bạn có thể sử dụng một đĩa RAM. Tôi cũng đảm bảo rằng 'Main.java' là ** lớn ** vì vậy bạn thực sự kiểm tra biên dịch so với tải/lưu. Nhưng tất nhiên, câu hỏi thực sự là: Bạn đang cố gắng tối ưu hóa điều gì? Bởi vì nếu đó là toàn bộ quá trình, I/O là một yếu tố quan trọng bạn sẽ không muốn kiểm tra xung quanh. –

Trả lời

27

Trình biên dịch java đã xử lý phân chia công việc của mình trên bộ vi xử lý có sẵn, ngay cả khi chỉ có biên soạn một tập tin duy nhất. Do đó, chạy các cá thể trình biên dịch riêng biệt song song với bản thân bạn sẽ không mang lại hiệu suất cao mà bạn mong đợi.

Để chứng minh điều này, tôi đã tạo chương trình java lớn (1 triệu dòng, 10.000 phương pháp) trong một tệp có tên là Main1.java. Sau đó, tạo các bản sao bổ sung là Main2.java đến Main8.java. Biên dịch thời gian được tính như sau:

một tệp biên dịch:

time javac Main1.java & --> (real) 11.6 sec 

Xem tập tin duy nhất này biên dịch trong top tiết lộ việc sử dụng bộ xử lý chủ yếu trong khoảng 200-400% (chỉ sử dụng nhiều CPU, 100% mỗi CPU) , với mức tăng đột biến trong phạm vi 700% (mức tối đa trên máy này là 800% vì có 8 bộ xử lý).

Tiếp theo, hai tập tin cùng một lúc:

time javac Main1.java & --> (real) 14.5 sec 
time javac Main2.java & --> (real) 14.8 sec 

Vì vậy, nó chỉ mất 14,8 giây để biên dịch hai, khi nó mất 11,6 giây để biên dịch một. Đó chắc chắn là phi tuyến tính. Rõ ràng là bằng cách nhìn vào top trong khi chúng được chạy lại, mỗi trình biên dịch java chỉ tận dụng tối đa bốn CPU cùng một lúc (với số lần tăng đột biến cao hơn). Bởi vì điều này, hai trình biên dịch chạy trên tám CPU chủ yếu là song song với nhau.

Tiếp theo, bốn tập tin cùng một lúc:

time javac Main1.java & --> (real) 24.2 sec 
time javac Main2.java & --> (real) 24.6 sec 
time javac Main3.java & --> (real) 25.0 sec 
time javac Main4.java & --> (real) 25.0 sec 

Được rồi, ở đây chúng tôi đã đâm vào tường. Chúng tôi không còn có thể song song với trình biên dịch nữa. Bốn tập tin mất 25 giây khi hai người mất 14,8. Có một chút tối ưu hóa ở đó nhưng nó chủ yếu là tăng thời gian tuyến tính.

Cuối cùng, Tám cùng một lúc:

time javac Main1.java & --> (real) 51.9 sec 
time javac Main2.java & --> (real) 52.3 sec 
time javac Main3.java & --> (real) 52.5 sec 
time javac Main4.java & --> (real) 53.0 sec 
time javac Main5.java & --> (real) 53.4 sec 
time javac Main6.java & --> (real) 53.5 sec 
time javac Main7.java & --> (real) 53.6 sec 
time javac Main8.java & --> (real) 54.6 sec 

Đây là thực sự là một chút tồi tệ hơn tuyến tính, như tám mất 54,6 giây trong khi bốn chỉ mất 25,0.Vì vậy, tôi nghĩ rằng takeaway từ tất cả điều này là để có niềm tin rằng trình biên dịch sẽ làm một công việc phong nha cố gắng để tối ưu hóa công việc bạn cung cấp cho nó trên các nguồn tài nguyên CPU có sẵn, và cố gắng thêm song song bổ sung bằng tay sẽ có giới hạn (nếu có) lợi ích.

Edit:

Để tham khảo, có hai mục tôi tìm thấy trong cơ sở dữ liệu lỗi của Oracle liên quan đến việc tăng cường javac để tận dụng nhiều bộ xử lý:

  • Bug ID: JDK-6629150 - Việc khiếu nại ban đầu, đây là cuối cùng được đánh dấu là bản sao của:
  • Bug ID: JDK-6713663 - Đề xuất độ phân giải và dựa trên "Ngày được giải quyết" có vẻ như hỗ trợ đa bộ xử lý trong javac đã được thêm vào ngày 2008-06-12.
+1

giải thích tốt đẹp, nhưng nếu chúng ta lấy 8 hello java thế giới (ngược lại với bạn) biên dịch tập tin sau đó parallely sử dụng 8 javac trên một máy 8 lõi sau đó nó nên đã hoàn thành trong 1 giây .... phải không? – Bhuvan

+0

@ user2410148: sử dụng tệp "Hello world" nhỏ mà tôi đã nhận được các lần biên dịch sau: 1 mất 0.32 giây; 2 mất 0,39 giây; 4 mất 0,54 giây; 8 mất 1,02 giây. Dường như đi theo cùng một khuôn mẫu, nơi mà nó chia thành hai biên dịch song song được, nhưng sau đó cố gắng làm bốn hoặc tám là một sự gia tăng tuyến tính hơn trong thời gian. Tôi nghĩ rằng khái niệm tương tự cũng áp dụng trên quy mô nhỏ: hãy để trình biên dịch thực hiện song song cho bạn. –

+0

Tôi không nghĩ rằng kết luận của bạn là âm thanh. Để chứng minh quan điểm của bạn, bạn có nên tính thời gian để biên dịch 1-8 trong chuỗi không? Nếu không, bạn đang so sánh hai lượng công việc khác nhau. Theo ước tính của tôi về số của bạn tôi có thể bắt đầu javac và chờ 88 giây hoặc tôi có thể song song nó từ dòng lệnh và chờ 55 giây. Hầu hết các tệp java của tôi nằm trong phạm vi 500 dòng, tôi đoán javac sẽ khó khăn hơn khi sử dụng nhiều lõi trong các tệp/lớp nhỏ hơn. Tôi không nói rằng 16.000 song song javac là giải pháp lý tưởng nhưng tôi không đồng ý với những lời khuyên để chỉ có niềm tin. – Ryan

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