2010-10-10 34 views
14

Trong tham chiếu đến fastest sort of fixed length 6 int array, tôi không hoàn toàn hiểu cách này sorting network đánh bại một thuật toán như insertion sort.Mạng phân loại đánh bại thuật toán phân loại chung như thế nào?

Mẫu câu hỏi đó, đây là một so sánh về số lượng CPU chu kỳ thực hiện để hoàn thành việc sắp xếp:

Linux 32 bit, gcc 4.4.1, Intel Core 2 Quad Q8300, -O2

  • Insertion Sort (Daniel Stutzbach): 1425
  • Networks Sorting (Daniel Stutzbach): 1080

Mã được sử dụng như sau:

Insertion Sort (Daniel Stutzbach)

static inline void sort6_insertion_sort_v2(int *d){ 
    int i, j; 
    for (i = 1; i < 6; i++) { 
      int tmp = d[i]; 
      for (j = i; j >= 1 && tmp < d[j-1]; j--) 
        d[j] = d[j-1]; 
      d[j] = tmp; 
    } 
} 

Networks Sorting (Daniel Stutzbach)

static inline void sort6_sorting_network_v1(int * d){ 
#define SWAP(x,y) if (d[y] < d[x]) { int tmp = d[x]; d[x] = d[y]; d[y] = tmp; } 
    SWAP(1, 2); 
    SWAP(0, 2); 
    SWAP(0, 1); 
    SWAP(4, 5); 
    SWAP(3, 5); 
    SWAP(3, 4); 
    SWAP(0, 3); 
    SWAP(1, 4); 
    SWAP(2, 5); 
    SWAP(2, 4); 
    SWAP(1, 3); 
    SWAP(2, 3); 
#undef SWAP 
} 

tôi understan d rằng các mạng phân loại thực sự tốt để phân loại song song, bởi vì một số bước độc lập với các bước khác. Nhưng ở đây chúng tôi không sử dụng song song.

Tôi hy vọng nó sẽ nhanh hơn, vì nó có lợi thế là biết chính xác số lượng các yếu tố trước đó. Vị trí và lý do chính xác việc chèn sắp xếp thực hiện các so sánh không cần thiết?

EDIT1:

Đây là đầu vào thiết lập các mã được so sánh với:

int d[6][6] = {\ 
    {1, 2, 3, 4, 5, 6},\ 
    {6, 5, 4, 3, 2, 1},\ 
    {100, 2, 300, 4, 500, 6},\ 
    {100, 2, 3, 4, 500, 6},\ 
    {1, 200, 3, 4, 5, 600},\ 
    {1, 1, 2, 1, 2, 1}\ 
};\ 
+0

Thứ tự của mảng nhập liệu ngẫu nhiên ở đây? Hoặc bạn đang sử dụng một mảng giảm dần? –

+0

@crypto: câu hỏi đã được cập nhật! – Lazer

Trả lời

19

Nhưng ở đây chúng tôi không sử dụng sự song song.

CPU hiện đại có thể tìm ra khi nào các lệnh độc lập và sẽ thực thi song song. Do đó, mặc dù chỉ có một luồng, song song của mạng phân loại có thể được khai thác.

Sắp xếp chèn chính xác ở đâu để so sánh không cần thiết?

Cách dễ nhất để xem so sánh bổ sung là làm ví dụ bằng tay.

Insertion sort: 
6 5 4 3 2 1 
5 6 4 3 2 1 
5 4 6 3 2 1 
4 5 6 3 2 1 
4 5 3 6 2 1 
4 3 5 6 2 1 
3 4 5 6 2 1 
3 4 5 2 6 1 
3 4 2 5 6 1 
3 2 4 5 6 1 
2 3 4 5 6 1 
2 3 4 5 1 6 
2 3 4 1 5 6 
2 3 1 4 5 6 
2 1 3 4 5 6 
1 2 3 4 5 6 

Sorting network: 
6 5 4 3 2 1 
6 4 5 3 2 1 
5 4 6 3 2 1 
4 5 6 3 2 1 # These three can execute in parallel with the first three 
4 5 6 3 1 2 # 
4 5 6 2 1 3 # 
4 5 6 1 2 3 
1 5 6 4 2 3 
1 2 6 4 5 3 
1 2 3 4 5 6 
1 2 3 4 5 6 
+1

@Daniel: Được rồi, vì những đường dẫn này hoàn toàn khác nhau, chúng tôi không thể so sánh chúng trực tiếp. Chắc chắn, Phân loại mạng cho phép chúng tôi sắp xếp theo số lượng so sánh thấp hơn. Để nêu câu hỏi của tôi theo một cách khác, ** điều gì ngăn chúng tôi tối ưu hóa việc sắp xếp chèn để sử dụng chuỗi hoán đổi này cho bất kỳ số lượng đầu vào nào? ** – Lazer

+0

Lazer: Tôi e là tôi không hiểu. Bạn đang đề cập đến chuỗi nào khi bạn nói "chuỗi các giao dịch hoán đổi" này? Ngoài ra, bạn có muốn nói "tối ưu hóa sắp xếp chèn" hoặc bạn có ý định tham chiếu đến các mạng phân loại không? –

+2

@Daniel: Xin lỗi vì thiếu sự rõ ràng. Tuy nhiên, về các thuật ngữ khác, tại sao chúng ta sử dụng sắp xếp chèn nếu tất cả các mạng phân loại hiệu quả hơn *? – Lazer

1

Tôi nghĩ rằng loop unwinding là những gì gây ra kết quả nhanh hơn trên các thuật toán mạng loại

0

Về mặt lý thuyết, mã có thể giống nhau nếu trình biên dịch hoàn toàn có thể hủy bỏ vòng lặp trong Sắp xếp Chèn. Vòng lặp đầu tiên có thể dễ dàng được kiểm tra, trong khi vòng lặp thứ hai không thể được unrolled dễ dàng. Nó cũng có thể là trường hợp đó, vì mã không đơn giản như mã phân loại mạng, trình biên dịch có thể làm tối ưu hóa ít hơn. Tôi nghĩ rằng có nhiều phụ thuộc hơn trong việc sắp xếp chèn hơn là trong sắp xếp mạng, có thể tạo ra sự khác biệt lớn khi trình biên dịch cố gắng tối ưu hóa mã (sửa tôi nếu tôi sai).

0

Tôi nghĩ rằng tất cả các bạn những câu hỏi được trả lời trong Daniel Stutzbach câu trả lời cho các bài bản gốc:

Thuật toán bạn đăng là tương tự như một loại chèn, nhưng có vẻ như bạn đã giảm thiểu số lượng hoán đổi với chi phí so sánh nhiều hơn. So sánh là đắt hơn nhiều so với các giao dịch hoán đổi , vì các chi nhánh có thể gây ra đường ống dẫn đến gian hàng.

+0

Bạn không thể thực hiện việc khái quát hóa đó.Nếu đối tượng dữ liệu của bạn lớn nhưng trích xuất và so sánh khóa là nhanh, thì so sánh sẽ rẻ hơn rất nhiều so với giao dịch hoán đổi. Tôi đoán thời gian hoán đổi duy nhất rẻ hơn là khi các yếu tố dữ liệu của bạn là một loại đơn giản. –

1

Tôi tin rằng lượng 'công việc' được thực hiện bằng thuật toán song song và thuật toán nối tiếp luôn gần như giống nhau. Chỉ vì công việc được phân phối, bạn sẽ nhận được kết quả đầu ra nhanh hơn. Tôi nghĩ rằng bạn sẽ nhận được đầu ra thuyết phục nhanh hơn trong trường hợp khi kích thước của đầu vào là đủ, đủ để biện minh bằng cách sử dụng thuật toán song song.

Trong trường hợp phân chia sắp xếp của mảng giữa các bộ xử lý sao cho nó tạo thành một đường ống, và sẽ mất một thời gian để điền vào đường ống và sau đó nó sẽ tạo ra lợi ích của thuật toán song song.

4

Câu hỏi hay hơn là tại sao mạng phân loại chỉ hoạt động tốt hơn sắp xếp chèn (thường là loại sắp xếp rất chậm) ~ 50%. Câu trả lời là big-O không quá quan trọng khi n rất nhỏ. Đối với câu hỏi của OP, Daniel có câu trả lời tốt nhất.

+0

nó vẫn còn quan trọng! khi bạn có 1000000 loại nhỏ xíu, ngay cả một sự khác biệt nhỏ sẽ tạo ra một sự thay đổi. –

+1

@DenRoman: Big-O không phải là điều quan trọng khi bạn có 1000000 loại nhỏ. Thay vào đó, yếu tố không đổi là điều quan trọng trong trường hợp này. –

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