Có phải là thực hành tốt để thay thế phép chia bằng phép nhân khi có thể?


73

Bất cứ khi nào tôi cần phân chia, ví dụ, kiểm tra điều kiện, tôi muốn cấu trúc lại biểu thức của phép chia thành phép nhân, ví dụ:

Phiên bản gốc:

if(newValue / oldValue >= SOME_CONSTANT)

Phiên bản mới:

if(newValue >= oldValue * SOME_CONSTANT)

Bởi vì tôi nghĩ rằng nó có thể tránh:

  1. Chia cho số không

  2. Tràn khi oldValuenhỏ

Có đúng không? Có một vấn đề cho thói quen này?


41
Hãy cẩn thận rằng với số âm, hai phiên bản kiểm tra những thứ hoàn toàn khác nhau. Bạn có chắc chắn điều đó oldValue >= 0?
dùng2313067

37
Tùy thuộc vào ngôn ngữ (nhưng đáng chú ý nhất là với C), bất kỳ tối ưu hóa nào bạn có thể nghĩ đến, trình biên dịch thường có thể làm điều đó tốt hơn, -OR- , có đủ ý nghĩa để không làm điều đó.
Mark Benningfield

63
Không bao giờ là "một thực hành tốt" để luôn thay thế mã X bằng mã Y khi X và Y không tương đương về mặt ngữ nghĩa. Nhưng luôn luôn là một ý tưởng tốt để xem X và Y, bật bộ não, suy nghĩ về các yêu cầu là gì , và sau đó đưa ra quyết định trong hai lựa chọn thay thế là đúng hơn. Và sau đó, bạn cũng nên suy nghĩ về những thử nghiệm được yêu cầu để xác minh rằng bạn có sự khác biệt về ngữ nghĩa.
Doc Brown

12
@MarkBenningfield: Không phải bất cứ điều gì, trình biên dịch không thể tối ưu hóa cách chia cho số không. "Tối ưu hóa" mà bạn nghĩ đến là "tối ưu hóa tốc độ". OP đang suy nghĩ về một loại tối ưu hóa khác - tránh lỗi.
slebetman

25
Điểm 2 là không có thật. Phiên bản gốc có thể tràn cho các giá trị nhỏ, nhưng phiên bản mới có thể tràn cho các giá trị lớn, vì vậy không an toàn hơn trong trường hợp chung.
JacquesB

Câu trả lời:


74

Hai trường hợp phổ biến để xem xét:

Số nguyên

Rõ ràng nếu bạn đang sử dụng số học số nguyên (cắt ngắn), bạn sẽ nhận được một kết quả khác. Đây là một ví dụ nhỏ trong C #:

public static void TestIntegerArithmetic()
{
    int newValue = 101;
    int oldValue = 10;
    int SOME_CONSTANT = 10;

    if(newValue / oldValue > SOME_CONSTANT)
    {
        Console.WriteLine("First comparison says it's bigger.");
    }
    else
    {
        Console.WriteLine("First comparison says it's not bigger.");
    }

    if(newValue > oldValue * SOME_CONSTANT)
    {
        Console.WriteLine("Second comparison says it's bigger.");
    }
    else
    {
        Console.WriteLine("Second comparison says it's not bigger.");
    }
}

Đầu ra:

First comparison says it's not bigger.
Second comparison says it's bigger.

Số học dấu phẩy động

Ngoài việc phân chia có thể mang lại một kết quả khác khi nó chia cho 0 (nó tạo ra một ngoại lệ, trong khi phép nhân không), nó cũng có thể dẫn đến các lỗi làm tròn hơi khác nhau và kết quả khác nhau. Ví dụ đơn giản trong C #:

public static void TestFloatingPoint()
{
    double newValue = 1;
    double oldValue = 3;
    double SOME_CONSTANT = 0.33333333333333335;

    if(newValue / oldValue >= SOME_CONSTANT)
    {
        Console.WriteLine("First comparison says it's bigger.");
    }
    else
    {
        Console.WriteLine("First comparison says it's not bigger.");
    }

    if(newValue >= oldValue * SOME_CONSTANT)
    {
        Console.WriteLine("Second comparison says it's bigger.");
    }
    else
    {
        Console.WriteLine("Second comparison says it's not bigger.");
    }
}

Đầu ra:

First comparison says it's not bigger.
Second comparison says it's bigger.

Trong trường hợp bạn không tin tôi, đây là một Fiddle mà bạn có thể tự mình thực hiện và xem.

Các ngôn ngữ khác có thể khác nhau; Tuy nhiên, hãy nhớ rằng C #, giống như nhiều ngôn ngữ, triển khai thư viện dấu phẩy động chuẩn (IEEE 754) , do đó bạn sẽ nhận được kết quả tương tự trong các lần chạy chuẩn hóa khác.

Phần kết luận

Nếu bạn đang làm việc trên cánh đồng xanh , có lẽ bạn vẫn ổn.

Nếu bạn đang làm việc với mã kế thừa và ứng dụng là một ứng dụng tài chính hoặc nhạy cảm khác thực hiện số học và được yêu cầu cung cấp kết quả nhất quán, hãy thận trọng khi thay đổi xung quanh các hoạt động. Nếu bạn phải, hãy chắc chắn rằng bạn có các bài kiểm tra đơn vị sẽ phát hiện bất kỳ thay đổi tinh tế nào trong số học.

Nếu bạn chỉ làm những việc như đếm các phần tử trong một mảng hoặc các hàm tính toán chung khác, có lẽ bạn sẽ ổn. Tuy nhiên, tôi không chắc phương thức nhân làm cho mã của bạn rõ ràng hơn.

Nếu bạn đang triển khai thuật toán cho một đặc tả, tôi sẽ không thay đổi gì cả, không chỉ vì vấn đề làm tròn lỗi, mà để các nhà phát triển có thể xem lại mã và ánh xạ từng biểu thức trở lại đặc tả để đảm bảo không có triển khai sai sót.


41
Thứ hai bit tài chính. Loại công tắc này đang yêu cầu các kế toán viên theo đuổi bạn bằng những cú ném bóng. Tôi nhớ 5.000 dòng mà tôi đã phải nỗ lực nhiều hơn để giữ cho các cú ném bóng bay hơn là tìm câu trả lời "đúng" - điều này thực sự hơi sai. Bị giảm 0,01% không thành vấn đề, câu trả lời hoàn toàn nhất quán là bắt buộc. Do đó, tôi buộc phải thực hiện phép tính theo cách gây ra lỗi vòng hệ thống.
Loren Pechtel

8
Hãy nghĩ đến việc mua kẹo 5 xu (không còn tồn tại nữa.) Mua 20 miếng, câu trả lời "đúng" là không có thuế vì không có thuế đối với 20 lần mua một miếng.
Loren Pechtel

24
@LorenPechtel, đó là bởi vì hầu hết các hệ thống thuế bao gồm một quy tắc (vì lý do rõ ràng) rằng thuế được đánh trên mỗi giao dịch và thuế được tính theo mức tăng không nhỏ hơn đồng xu nhỏ nhất của vương quốc và số tiền phân số được làm tròn theo lợi của người nộp thuế. Những quy tắc đó là "chính xác" bởi vì chúng là hợp pháp và nhất quán. Các kế toán viên với cây chĩa có thể biết các quy tắc thực sự là gì theo cách mà các lập trình viên máy tính sẽ không (trừ khi họ cũng là kế toán viên có kinh nghiệm). Lỗi 0,01% có thể sẽ gây ra lỗi cân bằng và việc có lỗi cân bằng là bất hợp pháp.
Steve

9
Bởi vì tôi chưa bao giờ nghe thuật ngữ greenfield trước đây, tôi đã tra cứu nó. Wikipedia nói rằng đó là "một dự án thiếu bất kỳ ràng buộc nào được áp đặt bởi công việc trước đó".
Henrik Ripa

9
@Steve: Gần đây, ông chủ của tôi đã đối chiếu "trường xanh" với "trường nâu". Tôi nhận xét rằng một số dự án nhất định giống như "trường đen" ... :-D
DevSolar

25

Tôi thích câu hỏi của bạn vì nó có khả năng bao gồm nhiều ý tưởng. Nhìn chung, tôi nghi ngờ câu trả lời là nó phụ thuộc , có thể phụ thuộc vào các loại liên quan và phạm vi giá trị có thể có trong trường hợp cụ thể của bạn.

Bản năng ban đầu của tôi là phản ánh về phong cách , tức là. phiên bản mới của bạn không rõ ràng đối với người đọc mã của bạn. Tôi tưởng tượng rằng tôi sẽ phải suy nghĩ trong một hoặc hai giây (hoặc có thể lâu hơn) để xác định ý định của phiên bản mới của bạn, trong khi phiên bản cũ của bạn ngay lập tức rõ ràng. Khả năng đọc là một thuộc tính quan trọng của mã, do đó, có một chi phí trong phiên bản mới của bạn.

Bạn có quyền rằng phiên bản mới sẽ tránh sự phân chia bằng không. Chắc chắn bạn không cần phải thêm một người bảo vệ (dọc theo dòng if (oldValue != 0)). Nhưng điều này có ý nghĩa? Phiên bản cũ của bạn phản ánh tỷ lệ giữa hai số. Nếu số chia là 0, thì tỷ lệ của bạn không xác định. Điều này có thể có ý nghĩa hơn trong tình huống của bạn, tức là. bạn không nên tạo ra một kết quả trong trường hợp này.

Bảo vệ chống tràn là tranh cãi. Nếu bạn biết rằng newValuenó luôn lớn hơn oldValue, thì có lẽ bạn có thể đưa ra lập luận đó. Tuy nhiên, có thể có trường hợp (oldValue * SOME_CONSTANT)cũng sẽ tràn. Vì vậy, tôi không thấy nhiều lợi ích ở đây.

Có thể có một đối số rằng bạn có hiệu suất tốt hơn vì phép nhân có thể nhanh hơn phép chia (trên một số bộ xử lý). Tuy nhiên, sẽ phải có nhiều tính toán như thế này để đạt được mức tăng đáng kể, tức là. coi chừng tối ưu hóa sớm.

Nhìn chung về tất cả những điều trên, nói chung, tôi không nghĩ rằng sẽ có được nhiều thứ với phiên bản mới của bạn so với phiên bản cũ, đặc biệt là giảm sự rõ ràng. Tuy nhiên, có thể có những trường hợp cụ thể trong đó có một số lợi ích.


16
Ehm, phép nhân tùy ý có hiệu quả hơn so với phép chia tùy ý không thực sự phụ thuộc vào bộ xử lý, đối với các máy trong thế giới thực.
Ded repeatator

1
Ngoài ra còn có vấn đề số nguyên so với số học dấu phẩy động. Nếu tỷ lệ là phân số, việc phân chia cần phải được thực hiện trong dấu phẩy động, đòi hỏi phải đúc. Thiếu diễn viên sẽ gây ra lỗi vô ý. Nếu phân số xảy ra là một tỷ lệ giữa hai số nguyên nhỏ, thì việc sắp xếp lại chúng cho phép so sánh được tiến hành trong số học số nguyên. (Tại thời điểm đó, các đối số của bạn sẽ được áp dụng.)
rwong

@rwong Không phải lúc nào. Một số ngôn ngữ ngoài đó thực hiện phân chia số nguyên bằng cách bỏ phần thập phân, do đó không cần truyền.
T. Sar - Tái lập Monica

@ T.Sar Kỹ thuật bạn mô tả và ngữ nghĩa được mô tả trong câu trả lời là khác nhau. Ngữ nghĩa là liệu lập trình viên dự định câu trả lời là giá trị dấu phẩy động hay phân số; kỹ thuật bạn mô tả là phép chia bằng phép nhân đối ứng, đôi khi là phép tính gần đúng hoàn hảo (thay thế) cho phép chia số nguyên. Kỹ thuật thứ hai thường được áp dụng khi ước số được biết trước, bởi vì đạo hàm của đối ứng số nguyên (được dịch chuyển bởi 2 ** 32) có thể được thực hiện tại thời gian biên dịch. Làm điều đó trong thời gian chạy sẽ không có lợi vì nó tốn nhiều CPU hơn.
rwong

22

Không.

Có lẽ tôi gọi đó là tối ưu hóa sớm , theo nghĩa rộng, bất kể bạn đang tối ưu hóa hiệu suất , vì cụm từ thường nói đến, hoặc bất cứ điều gì khác có thể được tối ưu hóa, chẳng hạn như đếm cạnh , dòng mã hoặc thậm chí rộng hơn, những thứ như "thiết kế."

Việc thực hiện loại tối ưu hóa đó như một quy trình vận hành tiêu chuẩn sẽ đặt rủi ro về ngữ nghĩa của mã của bạn và có khả năng che giấu các cạnh. Các trường hợp cạnh bạn thấy phù hợp để loại bỏ âm thầm có thể cần phải được giải quyết rõ ràng bằng mọi cách . Và, cực kỳ dễ dàng hơn để gỡ lỗi các vấn đề xung quanh các cạnh ồn ào (những vấn đề ném ngoại lệ) so với những vấn đề thất bại trong âm thầm.

Và, trong một số trường hợp, thậm chí còn có lợi khi "tối ưu hóa" vì mục đích dễ đọc, rõ ràng hoặc làm chứng. Trong hầu hết các trường hợp, người dùng của bạn sẽ không nhận thấy rằng bạn đã lưu một vài dòng mã hoặc chu kỳ CPU để tránh xử lý trường hợp cạnh hoặc xử lý ngoại lệ. Mặt khác, mã lúng túng hoặc thất bại sẽ ảnh hưởng đến mọi người - ít nhất là đồng nghiệp của bạn. (Và, do đó, chi phí để xây dựng và bảo trì phần mềm.)

Mặc định cho bất cứ điều gì "tự nhiên" hơn và dễ đọc hơn đối với miền của ứng dụng và vấn đề cụ thể. Giữ cho nó đơn giản, rõ ràng và thành ngữ. Tối ưu hóa là cần thiết cho lợi ích đáng kể hoặc để đạt được ngưỡng khả năng sử dụng hợp pháp.

Cũng lưu ý: Trình biên dịch thường tối ưu hóa phân chia cho bạn bằng mọi cách - khi nào an toàn để làm như vậy.


11
-1 Câu trả lời này không thực sự phù hợp với câu hỏi, đó là về những cạm bẫy tiềm tàng của sự phân chia - không liên quan gì đến tối ưu hóa
Ben Cottrell

13
@BenCottrell Nó hoàn toàn phù hợp. Cạm bẫy là trong việc đặt giá trị trong tối ưu hóa hiệu suất vô nghĩa với chi phí bảo trì. Từ câu hỏi "có vấn đề gì cho thói quen này không?" - Đúng. Nó sẽ nhanh chóng dẫn đến việc viết vô nghĩa tuyệt đối.
Michael

9
@Michael câu hỏi không phải là hỏi về bất kỳ điều nào trong số những điều đó - nó đặc biệt hỏi về tính đúng đắn của hai biểu thức khác nhau, mỗi biểu thức có ngữ nghĩa và hành vi khác nhau, nhưng cả hai đều phù hợp với cùng một yêu cầu.
Ben Cottrell

5
@BenCottrell Có lẽ bạn có thể chỉ cho tôi biết trong câu hỏi có bất kỳ đề cập nào về tính đúng đắn không?
Michael

5
@BenCottrell Bạn nên nói 'Tôi không thể' :)
Michael

13

Sử dụng cái nào ít lỗi hơn và có ý nghĩa logic hơn.

Thông thường , chia cho một biến là một ý tưởng tồi, vì thông thường, số chia có thể bằng không.
Chia theo hằng số thường chỉ phụ thuộc vào ý nghĩa logic là gì.

Dưới đây là một số ví dụ để cho thấy nó phụ thuộc vào tình huống:

Phân chia tốt:

if ((ptr2 - ptr1) >= n / 3)  // good: check if length of subarray is at least n/3
    ...

Nhân xấu:

if ((ptr2 - ptr1) * 3 >= n)  // bad: confusing!! what is the intention of this code?
    ...

Nhân giống tốt:

if (j - i >= 2 * min_length)  // good: obviously checking for a minimum length
    ...

Phân chia xấu:

if ((j - i) / 2 >= min_length)  // bad: confusing!! what is the intention of this code?
    ...

Nhân giống tốt:

if (new_length >= old_length * 1.5)  // good: is the new size at least 50% bigger?
    ...

Phân chia xấu:

if (new_length / old_length >= 2)  // bad: BUGGY!! will fail if old_length = 0!
    ...

2
Tôi đồng ý rằng nó phụ thuộc vào ngữ cảnh, nhưng hai cặp ví dụ đầu tiên của bạn cực kỳ nghèo nàn. Tôi sẽ không thích cái này hơn cái kia trong cả hai trường hợp.
Michael

6
@Michael: Uhm ... bạn có thấy (ptr2 - ptr1) * 3 >= ndễ hiểu như cách diễn đạt ptr2 - ptr1 >= n / 3không? Nó không làm cho bộ não của bạn vấp ngã và trở lại cố gắng giải mã ý nghĩa của việc tăng gấp ba lần sự khác biệt giữa hai con trỏ? Nếu nó thực sự rõ ràng với bạn và nhóm của bạn, thì tôi đoán thêm sức mạnh cho bạn; Tôi phải ở trong nhóm thiểu số chậm.
Mehrdad

2
Một biến được gọi nvà số 3 tùy ý gây nhầm lẫn trong cả hai trường hợp, nhưng, được thay thế bằng tên hợp lý, không tôi không tìm thấy cái nào khó hiểu hơn cái kia.
Michael

1
Những ví dụ này không thực sự kém .. chắc chắn không phải là 'cực kỳ nghèo' - ngay cả khi bạn đặt vào 'tên hợp lý', chúng vẫn không có ý nghĩa khi bạn trao đổi chúng cho các trường hợp xấu. Nếu tôi chưa quen với một dự án, tôi sẽ thấy các trường hợp 'tốt' được liệt kê trong câu trả lời này khi tôi đi sửa một số mã sản xuất.
John-M

3

Làm bất cứ điều gì bất cứ khi nào có thể, rất hiếm khi là một ý tưởng tốt.

Ưu tiên số một của bạn phải là sự chính xác, tiếp theo là khả năng đọc và bảo trì. Thay thế một cách mù quáng sự phân chia bằng phép nhân bất cứ khi nào có thể thường sẽ thất bại trong bộ phận chính xác, đôi khi chỉ trong trường hợp hiếm và do đó khó tìm thấy trường hợp.

Làm những gì chính xác và dễ đọc nhất. Nếu bạn có bằng chứng chắc chắn rằng viết mã theo cách dễ đọc nhất gây ra vấn đề về hiệu năng, thì bạn có thể xem xét thay đổi nó. Chăm sóc, toán học và đánh giá mã là bạn bè của bạn.


1

Về khả năng đọc của mã, tôi nghĩ rằng phép nhân thực sự dễ đọc hơn trong một số trường hợp. Ví dụ: nếu có thứ gì đó mà bạn phải kiểm tra xem newValueđã tăng 5 phần trăm trở lên ở trên chưa oldValue, thì đó 1.05 * oldValuelà ngưỡng để kiểm tra newValuevà đó là điều tự nhiên khi viết

    if (newValue >= 1.05 * oldValue)

Nhưng hãy cẩn thận với các số âm khi bạn cấu trúc lại mọi thứ theo cách này (hoặc thay thế phép chia bằng phép nhân hoặc thay thế phép nhân bằng phép chia). Hai điều kiện bạn xem là tương đương nếu oldValueđược đảm bảo không âm tính; nhưng giả sử newValuethực sự là -13,5 và oldValuelà -10,1. Sau đó

newValue/oldValue >= 1.05

đánh giá là đúng , nhưng

newValue >= 1.05 * oldValue

đánh giá thành sai .


1

Lưu ý Phân chia giấy nổi tiếng theo Số nguyên bất biến bằng cách nhân .

Trình biên dịch thực sự đang thực hiện phép nhân, nếu số nguyên là bất biến! Không phải là một bộ phận. Điều này xảy ra ngay cả đối với sức mạnh không có 2 giá trị. Sức mạnh của 2 bộ phận sử dụng dịch chuyển bit rõ ràng và do đó thậm chí còn nhanh hơn.

Tuy nhiên, đối với các số nguyên không bất biến, bạn có trách nhiệm tối ưu hóa mã. Hãy chắc chắn trước khi tối ưu hóa rằng bạn thực sự tối ưu hóa một nút cổ chai chính hãng và sự đúng đắn đó không bị hy sinh. Cẩn thận với tràn số nguyên.

Tôi quan tâm đến tối ưu hóa vi mô, vì vậy tôi có thể sẽ xem xét các khả năng tối ưu hóa.

Cũng nghĩ về kiến ​​trúc mã của bạn chạy trên. Đặc biệt ARM có sự phân chia cực kỳ chậm; bạn cần gọi một hàm để chia, không có lệnh chia trong ARM.

Ngoài ra, trên các kiến ​​trúc 32 bit, phân chia 64 bit không được tối ưu hóa, như tôi đã tìm ra .


1

Chọn điểm 2 của bạn, nó thực sự sẽ ngăn chặn tràn cho rất nhỏ oldValue. Tuy nhiên, nếu SOME_CONSTANTcũng rất nhỏ thì phương thức thay thế của bạn sẽ kết thúc bằng dòng chảy, trong đó giá trị không thể được biểu diễn chính xác.

Và ngược lại, điều gì xảy ra nếu oldValuerất lớn? Bạn có những vấn đề tương tự, chỉ là cách ngược lại.

Nếu bạn muốn tránh (hoặc giảm thiểu) nguy cơ tràn / tràn, cách tốt nhất là kiểm tra xem newValuemức độ gần nhất với oldValuehoặc tới SOME_CONSTANT. Sau đó, bạn có thể chọn thao tác chia thích hợp

    if(newValue / oldValue >= SOME_CONSTANT)

hoặc là

    if(newValue / SOME_CONSTANT >= oldValue)

và kết quả sẽ chính xác nhất.

Đối với chia cho 0, theo kinh nghiệm của tôi, điều này gần như không bao giờ thích hợp để được "giải" trong toán học. Nếu bạn có một số chia cho các kiểm tra liên tục của mình, thì gần như chắc chắn bạn có một tình huống đòi hỏi một số phân tích và mọi tính toán dựa trên dữ liệu này là vô nghĩa. Một kiểm tra phân chia rõ ràng gần như luôn luôn là động thái thích hợp. (Lưu ý rằng tôi nói "gần như" ở đây, vì tôi không cho là không thể sai được. Tôi chỉ lưu ý rằng tôi không nhớ đã thấy một lý do chính đáng cho việc này trong 20 năm viết phần mềm nhúng và tiếp tục .)

Tuy nhiên, nếu bạn có nguy cơ thực sự tràn / tràn trong ứng dụng thì đây có lẽ không phải là giải pháp phù hợp. Nhiều khả năng, bạn thường nên kiểm tra tính ổn định số của thuật toán của mình hoặc có thể chỉ cần chuyển sang biểu diễn có độ chính xác cao hơn.

Và nếu bạn không có nguy cơ tràn / tràn đã được chứng minh, thì bạn không lo lắng gì cả. Điều đó có nghĩa là bạn thực sự cần phải chứng minh rằng bạn cần nó, với những con số, trong các bình luận bên cạnh mã giải thích cho người bảo trì tại sao lại cần thiết. Là một kỹ sư chính đang xem xét mã của người khác, nếu tôi gặp phải ai đó nỗ lực thêm về việc này, cá nhân tôi sẽ không chấp nhận bất cứ điều gì ít hơn. Điều này trái ngược với tối ưu hóa sớm, nhưng nhìn chung nó sẽ có cùng nguyên nhân gốc rễ - nỗi ám ảnh với chi tiết không có sự khác biệt về chức năng.


0

Đóng gói số học có điều kiện trong các phương pháp và tính chất có ý nghĩa. Việc đặt tên tốt không chỉ cho bạn biết "A / B" nghĩa là gì , việc kiểm tra tham số & xử lý lỗi cũng có thể ẩn gọn trong đó.

Điều quan trọng, vì các phương thức này được cấu thành thành logic phức tạp hơn, độ phức tạp bên ngoài vẫn rất dễ quản lý.

Tôi muốn nói thay thế nhân có vẻ là một giải pháp hợp lý bởi vì vấn đề không rõ ràng.


0

Tôi nghĩ rằng không thể thay thế phép nhân bằng các phép chia vì ALU (Đơn vị logic số học) của CPU thực thi các thuật toán, mặc dù chúng được triển khai trong phần cứng. Các kỹ thuật tinh vi hơn có sẵn trong các bộ xử lý mới hơn. Nói chung, các bộ xử lý cố gắng song song hóa các hoạt động của cặp bit để giảm thiểu các chu kỳ xung nhịp cần thiết. Các thuật toán nhân có thể được song song khá hiệu quả (mặc dù cần nhiều bóng bán dẫn hơn). Các thuật toán phân chia không thể được song song hóa một cách hiệu quả. Các thuật toán phân chia hiệu quả nhất là khá phức tạp. Nói chung, chúng đòi hỏi nhiều chu kỳ xung nhịp hơn trên mỗi bit.

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.