Trang 4 / 6 FirstFirst 123456 LastLast
Hiển thị kết quả từ 31 đến 40 / 53
  1. #31
    Tham gia
    02-02-2005
    Bài viết
    219
    Like
    0
    Thanked 3 Times in 3 Posts
    Quote Được gửi bởi lqkhoi View Post
    Bạn tham dự cái ddth này gần 3 năm rồi chẳng lẽ để bị ban vì những điều cỏn con này.

    Có những việc mà khi bạn đứng ở tuốt trên cao lập trình DOT NET bạn thấy sự việc nó như thế này. Bạn xuống dưới thấp sự việc nó lại là 1 chuyện khác.

    Bạn nói để CPU nó tự "xử lý" (not "sử lý") là bạn chưa bao giờ viết trên 1 Real time OS. Trong Realtime OS thread nào có priority cao hơn sẽ control toàn bộ hệ thống vì thế tôi có thể dễ dàng cho em CPU run 100% chỉ với việc set task của tôi lên priority lên max và cho 1 cái while(1){}

    Chuyện nguy hiểm ngược lại là bạn phải biết bạn đang làm gì ? Bạn phải biết thread nào của bạn cần độ ưu tiên cao hơn, và để giải quyết chuyện đó cũng phải cần 1 chút xíu đến những bài toán xử lý song song tuy parallel phức tạp hơn những chuyện như thế. Chắc bạn chưa bao giờ làm trong những project mà việc đặt priority của các task cũng phải được cân nhắc cẩn thận, với nhiều discussion, document. Vì thế chẳng bao giờ CPU làm tất cả cho bạn cả đặc biệt khi bạn làm low level.

    Dạ thưa. Tôi đã viết hệ điều hành cho MCU và ARM được khá lâu rồi ạ. Tôi không những đã xây dựng được hệ điều hành cụ thể mà cả mô hình hệ điều hành cho chúng, cùng với những thư viện cần thiết 7 năm rồi ạ, cùng cả mô hình mạng, hỏi vòng.... Tất cả đều bằng ASM, kiểu ASM đặc biệt cho chúng.

    Khi viết những ứng dụng real time đó người ta đều sùng ASM. MCU thiết kế thông thường chạy một lệng hết 0,3 phần triệu giây, các chip tích hợp nhanh gấp mười, cũng chỉ vài lệnh hét 1/triệu giây. Để hệ thống trả lời trong 1/triệu giây cần cân nhắc từng chút một và cần viết ASM. Tôi đã phải trải qua những hỏi vòng, những nhiều đầu vào, những xác định mấy chu kỳ (do không sử lý kịp)....

    PC không thể là một hệ thống real time nên tất cả những gì bám vào nó đều không đủ đáp ứng real time. PC được thiết kế để thực hiện giao tiếp người dùng-hệ thống. Vì người mắt tay đều chậm nên chẳng cần real time làm gì. Chính vì không được thiết kế real time nên các ngắt ngoài gây ra đều có buffer, chính buffer lại ngăn những khả năng real time của hệ thống. Trong máy tính, hệ thống real time duy nhất là RTC. RTC của máy 586 là con MC146818. Con này bao gồm 1 đồng hồ có đầu giao tiếp song song 8 bit, đầu ra gây ngắt và một ít ram. Sau này nó được tích hợp vào chip set, nằm trong PII X4. Để giao tiếp với nó dùng cổng 70h và 71h (addr và data).
    http://pdf1.alldatasheet.com/datashe.../datasheet.pdf
    Con này gây ngắt tối đa 1000 phát/giây, đã quá không thể chấp nhận với real time. Nhưng các buffer IO còn kéo chu kỳ xuống còn 1/vài chục giây.

    Real time bắt buộc phải chạy trên hệ thống tính toán định hướng, một luồng và không cache. CHỉ trong những hệ thống đó mới có phân biệt trình tự trước sau, có phân biệt trình tự như thế mới có khái niệm thời gian, có khái niệm thời gian mới có khái niệm thời gian thực. Cấu tạo định hướng đó đã được PC chào từ Intel 286.
    Hệ thống real time ổn định điển hình có một khái niệm là chu kỳ sử lý. Đây là đơn vị đánh giá quan trọng nhất của hệ. Khi đến đầu chu kỳ, máy đọc hết dữ liệu, sử lý và trả lời, tất cả phải diễn ra dưới thời gian 1 chu kỳ để sẵn sàng cho chu kỳ mới. Các chu kỳ cho máy in kim cổ lỗ đã phần vạn giây. Nếu sử lý khong kịp 1 chu kỳ phải nhạn ra lỗi, néu không được như thé thì hệ đổ vỡ. Bạn có biết người ta gọi hiẹn tược đổ vỡ đó là gì không: Vụ Nổ Tréc Nô Bưn.

    Tôi nhắc lại những gì tôi đã viết nhé.
    Cấu tạo máy tính của chúng ta ngày nay là cấu tạo vô hướng, cấu tạo scalar.

    Cấu tạo đó mô tả như thế này:
    có một con đường độc đạo các ô tô nối nhau đi, trong đó có rất nhiều biển: 29, 80, hải phòng, lạng sơn......
    Yêu cầu là các ô tô có biển cùng tỉnh phải đi theo đúng thứ tự trước sau nhưng khác tính thì không cần.
    Đoàn xe đi từ con đường độc đạo đến một bãi rộng.
    Tự nhiên hình thành các đoàn xe cùng tỉnh đi hàng một và các đoàn này tách khỏi tỉnh khác.
    Đoàn xe trở thành đoàn rất nhiều hàng dọc, mỗi hàng dọc một tỉnh, các hàng dọc tiến song song.
    Đó là cơ chế pipe line, cơ sở của cấu trúc CPU hiện tại. Việc tách luồng tiến hành song song các luồng được làm một cách tự động, không cần phải nghĩ. Như tôi đã ví dụ, tính 1000!.

    Nhìn lại đoàn xe trên. Tuy tằng tổng tốc độ thông qua của cả khối xe rất lớn nhưng tốc độ mỗi xe vẫn không nhanh hơn được. Đó là lý do PC không thể là các hệ thống real time. Một dữ liệu, ví dụ đọc ở đầu chu kỳ, vẫn phải trôi lâu đằng đẵng trong CPU, dù có đa luồng đa nhân đều không thể giảm thời gian một lệnh trôi trong sử lý, nó chỉ cho nhiều lệnh trôi đồng thời. Đó là lý do real time và cache kỵ nhau.

    Những cái được coi là real time của PC như X windows (XII và X), RITAI linux đều chỉ đủ để xem multi media thôi. PC không thể có chu kỳ dưới 1/1000 giây về lý thuyết.
    ------------------

    Trở lại vẫn đề chip của bạn chạy một nửa.
    Thứ nhất, tôi hỏi bạn đã làm 1000 giai thừa tôi gợi ý chưa. Bạn đã thử open một tậo DOC 1000 trang ảnh và đánh máy vào trang đầu như tôi gợi ý chưa ????
    Tôi đã thử điều đó trên cỗ máy 16 GB RAM, 4 CPU Xeon. Máy đa chip có chênh lệch tốc đọ lõi / tốc độ bus cao hơn nhiều 1 chip đa nhân, nên dễ bị nghẹt cổ chai hơn.

    Bạn hiểu ý tôi nói chưa. Bạn hiẻu cái ngu của bạn chưa ????

    CPU không cần người viết chương trình diễn giải song song bài toán của họ. Công việc đó được dùng cho những bài toán rất lớn, phải thực hiện nhiều lần trên nhiều máy tính chứ không phải trong 1 CPU. Như tôi đã nói nhiều lần mà bạn không hiểu, các nhà toán học đã nhét vào trong máy công cụ để tách luồng song song tự động, không khiến bạn làm.

    Nếu bạn vẫn không hiểu thì tôi dẫn giải cái sai của bạn nhé. Những học sính mới học lập trình vài ngày rất hay gặp lỗi này: vòng lặp vô tận.

    CPU có thể chọn ra những dãy dữ liệu liên quan và không liên quan, sử lý song song những dãy dữ liệu không liên quan. Đó là cơ chế pipeline, cấu trúc máy kiểu đó là cấu trúc vô hướng scalar.

    Trên nguyên tắc đó, một while ngu ngốc không lối thoát không thể tách ra làm song song nhiều vòng. Vì những lệnh vòng sau, những dữ liệu vòng sau nằm trên chuỗi liên quan vòng trước. Vậy, gặp một vòng while ngu ngốc máy không thể kết thúc event và rơi vào tình trạng nghẹt event: "not responding".

    Bạn đã hiểu rồi chứ. Có lẽ, tôi vẫn chưa tin là bạn hiểu, vì khả năng lập luận của bạn quá kém.

    Bạn đã hiẻu rồi chứ, điều đó quá ngược với chu kỳ sử lý của real time, phải kết thúc thật nhanh. Bạn đã hiểu tôi đã định nghĩa hệ thống real time rồi chứ: là sự kết hợp của các cấu trúc cảm biến real time tốc độ cao và trung tâm sử lý mạnh. Đọc lại các bài trước của tôi nhé.

    Đến bây giờ bạn đã hiẻu tại sao có một nửa rỗi rãi rồi chứ. Nếu chương trình, nói đúng hơn là cái vòng while ngu ngốc của bạn chạy trên 586 thì chỉ còn nước rút dây nguồn tháo pin bấm reset (nếu có). May là CPU của bạn 2 lõi, nên nó để rỗi một lõi để kết thúc cái vòng while ngu ngốc bằng task manager. Bạn đã hiểu chưa. Bạn đã biết công dụng của 1 nửa nghỉ ngơi chưa ????

    Các máy hiện đại như IBP P590
    http://www-03.ibm.com/systems/p/hardware/
    Chúng chia mỗi CPU vật lý ra làm 10 phần. Khi bạn đến thua máy, tùy tiền của bạn mà họ cho bạn mấy cái 1/10 đó. Lỹ sự như bạn, nếu bạn không đủ tiền thuê một lõi vật lý thì không thể chạy chương trình sao ????
    Và không ai mua chíp 2 lõi để chậm đi cả.

  2. #32
    Tham gia
    02-02-2005
    Bài viết
    219
    Like
    0
    Thanked 3 Times in 3 Posts
    Tôi vẫn cảm thấy rằn những tiến sỹ anh tài trong này chưa hiểu vấn đề. Linh cảm của tôi khá đúng, vì theo phpong cách lập luận của họ, họ nói mẽ mà không hiểu vấn đề, kể cả rất đơn giản.
    Đến giờ tôi lại nói chuyện với các bạn về 1000!. Tôi gợi ý với các bạn dùng string để làm phải không.

    Bây giờ, chúng ta giả sử có một cái máy biểu diễ được 2500 chứ số nguyên xem cái gì xảy ra nhẽ. Tôi giả sử như thế để dơn giản bào toán.

    Trên tôi vừa nói chuyện với các bạn về cấu trúc scalar trong CPU đúng không. Đó chỉ là một nửa của vấn đề thôi, nhưng cứ dừng ở đấy đã.
    Bây giờ, lấy cái máy 2 vạn bít đó tính 1000!.
    Đơn giản:

    n=1;
    gt=1;
    do
    {
    gt=gt*n;
    n++;
    }
    while (n<1001);

    hay là:
    gt=1;
    For (n=1; n<1001; n++)
    gt=gt*n;

    đơn giản nữa gt=1*2*3...*1000;

    Hiện nay cậu chỉ biết có một chương trình dịch làm hai đoạn này hiẹu quả như nhau, nhưng cái đó hơi cổ, chỉ có giá trị lý thuyết.
    Còn thường, theo phân tích dưới đây, các bạn tự đánh giá các đoạn mã.

    Scalar và Vector (vô hướng và định hướng).
    Vector: máy sẽ làm 1000 bước. Đây là hệ máy real time.
    gt=1*2
    gt=gt*3
    ...
    gt=gt*1000
    hết


    Scalar:
    Nhưng bây giờ máy có pile nó sẽ xem xem có thằng nào làm trước được thì làm. Giả sử số phần tử sử lý vô tận (với 1000! thì xeon coi như vô tận)

    bước 1 (ống đùn vào phần tử sử lý đầu tiên, phần tử nào truy cập ô nhớ nào liền đánh dấu)
    1*2=t1

    bước 2 (ống đùn vào phần tử sử lý kế, phần tử này thấy rằng có khối thứ có thể làm trước được bằng cách nhìn chỗ đánh dấu ô nhớ)
    3*4=t2 (phần tử sử lý 2 làm)
    t1=t1*5 (phần tử sử lý 1 làm)

    bước 3
    t3=6*7 (phần tử sử lý 3 làm)
    t2=t2*8
    t1=t1*9

    bước 4
    t4=10*11 (phần tử sử lý 4 làm)
    t3=t3*12
    t2=t2*13
    t1=t1*14

    bước 5
    t5=15*16 (phần tử sử lý 5 làm)
    t4=t4*17 (phần tử sử lý 4 làm)
    t3=t3*18 (phần tử sử lý 3 làm)
    t2=t2*19 (phần tử sử lý 2 làm)
    t1=t1*20 (phần tử sử lý 1 làm)

    .....

    tk=tk*t(k-1)
    ...........


    chỉ 55 bước thay cho 1000 bước. Đây là hệ scalar dùng pipe line. Toàn bộ chíp nhanh chóng bị hút cạn tài nguyên sử lý.

    Hệ sử lý của các CPU chuyên dùng cho máy đa nhân như P5, P6 (Intel), Elrus (Nga), dặt các phần tử sử lý nằm dọc theo ống, có khả năng truy nhập ngẫu nhien ống. Nói nôm na là vị trí các phần tử như nhau về không gian và lệch một nhịp về thời gian. Người ta còn có kiẻu bắn chéo (ví dụ 1-3-5 2-4-6). Nhờ ký thuật này, trong pháp toán trên, CPU nhanh chóng tìm ta cách nhóm các nhóm số nguyên tố, mũ số nguyên tố bằng tra bảng.

    Các bạn so sánh dãy trên và vòng lặp ngu ngốc:
    do
    t=t*1;
    while true;

    Người ta không thể để hai phần tử sử lý cùng đọc và ghi vào t (vì các lần đọc ghi là tuần tự, bị đánh dấu). Như vậy là các phần tử khác ngồi chơi nhìn phần tử đầu tiên gặp t tung hứng với t.

    Đấy là nguyên nhân cơ bản của mấy cao nhân trên kia dùng nửa chip.
    Về viết lại chương trình di, chia ra dll, nhồi bảng vào data base....chẳng mấy mà giỏi như cậu dây.
    he he he he he he he he
    Được sửa bởi huyphuc1981_nb lúc 02:29 ngày 18-09-2007

  3. #33
    Tham gia
    26-12-2004
    Bài viết
    23
    Like
    0
    Thanked 0 Times in 0 Posts
    Quote Được gửi bởi huyphuc1981_nb View Post
    ...
    Người ta không thể để hai phần tử sử lý cùng đọc và ghi vào t (vì các lần đọc ghi là tuần tự, bị đánh dấu). Như vậy là các phần tử khác ngồi chơi nhìn phần tử đầu tiên gặp t tung hứng với t.

    Đấy là nguyên nhân cơ bản của mấy cao nhân trên kia dùng nửa chip.
    Về viết lại chương trình di, chia ra dll, nhồi bảng vào data base....

    Hi huyphuc1981_nb !

    Xem ra bạn rất thích "play with CPU theory" và dường như bạn luôn cho rằng cấu trúc vô hướng làm tất cả nếu mình có một chút chú ý khi lập trình là đủ ?!

    Mình đồng ý là cấu trúc vô hướng là tuyệt vời, thông thường thì nó phát huy tác dụng vì máy tính thường xuyên có nhiều việc để làm và những việc đó có thể được phân chia một cách tự động trong cấu trúc xử lý vô hướng. Nhưng mình vẫn không nghĩ là trong mọi trường hợp cấu trúc đó đều có thể pháp huy tác dụng.

    Bạn hãy thử một nghĩ xem giùm mình trong bài toán cụ thể sau đây thì nên tổ chức chương trình thế nào để cho CPU tự động phát huy cái sở trường vô hướng kia, có thể bạn có cách mà mình thì chưa thấy.

    ------------------------
    Bài toán: (Cách giải 1, cứ lập trình bình thường)

    Cần giải phương trình sau:
    M.A + K.U = F , gọi là bài toán (0)
    Trong đó:
    M=((m11,m12),(m21,m22)) = matran 2x2, là các hằng số cho trước
    K=((k11,k12),(k21,k22)) = matran 2x2, là các hằng số cho trước
    A = (a1,a2) = vector cột, là 2 đại lượng biến thiên theo thời gian t, cần tìm
    U = (u1,u2) = vector cột, là 2 đại lượng biến thiên theo thời gian t, cần tìm
    F = (f1,f2) = vector cột, là 2 đại lượng biến thiên theo thời gian t, cho trước.

    Quy luật để giải (gọi là phương pháp tích phân trực tiếp, thời gian được xem xét là các bước rời rạc t=i*dt) được chọn là quy luật đơn giản như sau:

    Giả sứ điều kiện ban đầu:
    A(0)= (0,0)
    U(0)= (0,0)
    V(0)= (0,0) (V là tích phân của A)

    Tại mỗi thời điểm t (t = i x dt, i = 1,2,...,n; dt là một time interval), các đại lượng U,V,A được tính như sau:
    V(i) = V(i-1) + A(i-1) * dt
    U(i) = U(i-1) + V(i-1)*dt + 0.5*A(i-1)*dt*dt
    A(i-1) = M1.[F(i-1) - K.U(i-1)]
    M1 = M(-1): nghĩa là nghịch đảo của ma trận M.

    Cứ cho biến i tăng dần từ 1 đến n và giải như thế cho đến bước thứ n là xong, ta có tập hợp tất cả các nghiệm (rời rạc) cần tìm U(i),A(i).

    Nếu lập trình truyền thống, cứ dùng 1 hàm với 1 cái for(i=1;i<n+1;i++) nên CPU 2 core cứ chạy có 50% thôi, rõ chán! Còn bạn thì chia dll, database và code như thế nào đây?


    --------------------
    Cách 2: (Làm giải thuật để tính toán song song bằng 2 threads)

    Vì chán cái cách 1 thế nên tôi phải làm thuật toán để giải song song. Kỹ thuật như sau: Tôi chia bài toán (0) ở trên làm 2 bài toán con (1) và (2) và có tương tác thơng qua f12, như sau:

    m1.a1 + k1.u1 = f1 + f12 (1)
    m2.a2 + k2.u2 = f2 - f12 (2)

    Trong đó:
    m1,m2,k1,k2 là các hằng số, được tính từ M,K ở trên.
    a1,a2,u1,u2: các đại lượng biến thiên như trên (cần tìm).
    f1,f2: các đại lượng biến thiên (cho trước) như trên.
    f12 = f12(u1,u2): gọi là tương tác, là một hàm của u1 và u2, có cách xác định hàm f12 này.

    Sau đó tôi giải song song bài toán con (1) và (2) đồng thời, quy luật giải cũng y như cách 1 ở trên nhưng chỉ khác là các đại lượng matran và vector (M,K,A,V,U,F) được thay bỡi các hằng số và biến (m1,m2,k2,k2,u1,u2,f1,f2), cũng tìm được các nghiệm rời rạc a1(i),a2(i),u1(i),u2(i), tương đương như cách 1.

    Kỹ thuật lập trình là dùng 2 threads, không ưu tiên. Vì phải tính cái tương tác f12 nên cần có 1 database đảm bảo đồng bộ 2 bài toán. Ở thời điểm cuối của mỗi bước i, cái nào xong trước thì phải chờ có kết quả của cái kia rồi mới làm bước tiếp theo.

    --------------------

    So với cách 1 ở trên thì cách 2 cái lợi ở đây là:

    - Thay vì tôi phải tính trên ma trận và vector bậc 2 (M, K, A, U, V,F), thì các phép tính đều tính trên số thực (m1, m2, k1, k2, u1, u2, v1, v2, a1, a2,f1+f12,f2-f12), xuất hiện thêm có phần tính tương tác f12. Với bài toán có ma trận bậc 2 là như thế, việc tiết kiệm số phép tính không đáng kể nhưng nếu các ma trận M,K mà bậc cao hơn, thậm chí (10000x10000) thì việc chia ra hai bài toán rồi giải sẽ mang lại hiệu quả cực kỳ cao nhờ việc giảm bậc của ma trận. -> Giảm khối lượng tính toán.

    - Vì dùng 2 threads nên có điều kiện để 2 core chạy cùng lúc được, nên tiết kiệm thời gian.


    Tổng hợp 2 ưu điểm: -> Giảm hơn gấp đôi thời gian tính toán.

    --------------------

    Đây là một bài toán ví dụ, tôi muốn tham khảo kiến của huyphuc1981_nb cùng các bạn, các bạn có ý tưởng nào về vấn đề này không?

    Van Thuan
    Được sửa bởi thuaniam lúc 08:02 ngày 18-09-2007

  4. #34
    Tham gia
    02-02-2005
    Bài viết
    219
    Like
    0
    Thanked 3 Times in 3 Posts
    Trời đất ôi. Thế ma trận 1000x 1000 cần 1000 core à.

    Tôi phân tích cho bạn nhé.

    Một cách ứng dụng real time hay được dùng:
    Đây là một cách làm thông thường được ứng dụng trong giải toán. Ứng dụng điển nhình của nó nôm na như sau: nó luôn đo đạc cách tốc độ tính toán và tùy vào tốc độ nhanh chậm, nó đưa ra quyết định sử dụng giải thuật, chấp nhận kết quả tồi để giải nhanh hay đợi kết quả tốt bằng thuật giải kỹ khi quỹ thời gian xông xênh.
    Phương pháp này được các chương trình nén nổi tiếng như KGB hay Skype sử dụng. Tôi cũng xây dựng phương pháp nén bằng cách này. Tuy vậy, tôi làm theo cách đơn giản hơn. Tôi dùng một luồng để đếm time với interval=1000. Mỗi cách chọn nhân nén tôi cho một luồng, mỗi time() tôi đánh giá lại và quyết định kill các luồng khi cần thiết.
    Đó là một ví dụ về real time với luồng. Bạn thân time đã là một thread.


    Về bài toán của bạn. Thứ nhát là, đây không phải là một hệ thống real time.

    Cái bài toán dở người của bạn có "đại lượng biến thiên theo thời gian t", vì vậy bạn gọi nó là "hệ thống real time", cái mà bạn gọi là interval thực ra là step. Bài toán của bạn không liên quan gì đến thời gian vật lý cả. Cách giải duy nhất của bài này là tính sẵn đồ thị F.
    Tuy vậy, bài toán của bạn dở người, nó không đủ yêu cầu giải được. Tôi nói nghiêm túc, khi bạn dang tưởng bạn là tiến sỹ thì bạn lại đang tẩu hỏa nhập ma. Bạn giải được bài toán đó là bạn sai. Hoặc bạn mô tả bài toán không đầy đủ.
    Yêu cầu để giải được ở đây là tương quan nữa cần được mô tả bằng chương trình.

    Theo như tôi đoán qua cái mà bạn mô tả thiếu thì đây là việc giải ma trận theo Gau-xơ. Bài toán của bạn cũng như ví dụ của tôi trên kia, nếu thực hiện tốt, bản thân step i đã được tách ra thành luồng riêng một cách tự động.
    Bạn lập trình còn non nên bạn không thẻ phân chia chức năng được thôi. Với nạp chống toán tử người ta đã hoàn toàn tổ chức các đối tượng như ma trận chưa biết rõ số hàng, đặt trong thư viện riêng.

    Ví dụ sử dụng thư viện như sau:
    ......................
    MT mt_n_h; //ma trận n hàng có kiểu ma trận
    mt_n_h.s_h=n; // có n hàng
    mt_n_h.init; // lấy không gian nhớ.

    MT mt_n_h_1; //ma trận n hàng có kiểu ma trận
    mt_n_h_1.sh=n; // có n hàng
    mt_n_h_1.init; // lấy không gian nhớ.

    xyz=mt_n_h_1*mt_n_h_1;
    ..................


    Một ví dụ về cái nhân ma trận này tôi đã viết là bài toán bình sai trắc địa, năm 1997, cái này khó hơn nhiều so với giải ma trận. Ngay lúc đó, dù máy có bận đến mấy thì các nút bấm trong giao diện vẫn chạy tốt (ví dụ để chọn chức năng ghi kết quả trung gian hay dừng chương trình). Tôi xây dựng một thư viện ma trận chưa biết số hàng, nạp chồng các toán tử cộng và nhân, định thức...
    Với cách tổ chức như thế, chương trình dịch Borland C++ dễ dàng tổ chức các nhóm biến và sau đó được CPU chia luồng ( Borland tốt hơn của MS chút, nhưng Borland C Builder 4 32 bit so với nay quá cổ). Tôi dự doán chạy được dến 5000x5000, hồi đó máy yếu nên chỉ dùng đến 1000x1000 để thử thôi.

    Bạn đọc lại ví dụ của tôi trên kia và phân tích ba cách viết 1000! nhé, bạn sẽ thấy tại sao C hay được dừng để thiết kế phầm mềm tiên tiến và chương trình dịch. Bạn cứ for như thế thì cho bạn for, wihile thì cứ while.

    Ở đây có một gợi ý. Do bạn tổ chức các đoạn code và data lằng nhằng, dẫn đến việc CPU không thể tách ra được, phải chạy như cái while ngu ngốc trên. Trong khi đó, nếu bạn định nghĩa thư viện tốt thì mặc định chương trình của bạn đã có nhiều luồng, như ví dụ MS Word trên. Ở đây, khi bạn đã tách ra làm hai luồng, thì hai luồng của bạn phải chờ nhau, đó là một phí phạm. Bạn phải chấp nhận cái phí phạm đó vì bạn chết nửa CPU. Thà dùng hai nửa mà phí còn hơn một nửa tiết kiệm. Bạn thấy tôi phân tích đúng chưa ???.

    Giải quyết theo cách của chuối đó của bạn, tôi có cách làm rất tiện, đỡ phải đọc bài ba thuật sắp xếp đua nhau trên 3 thread của Borland (tức là khỏi cần quan tâm đến thread), nghe này:
    -Bạn viết hai chương trình rời tính hai nửa dùng chung data base.
    Quá tít.
    Thật ra, đó là cách làm của MS Word, cách mà tôi bảo bạn chia ra các dll.... nó dễ dàng tận dụng máy nhiều CPU và mỗi CPU có cache cũng như các phần tử sử lý như Xeon.

  5. #35
    Tham gia
    02-02-2005
    Bài viết
    219
    Like
    0
    Thanked 3 Times in 3 Posts
    Ở đây, tôi nói thêm với các bạn một chút về đa luồng, đa nhân và đa phần tử sử lý. Đáng ra, những điểm mấu chốt của sử lý song song này câc bạn phải quan tâm hơn tôi, nhưng vì các bạn ngô nghê quá nên tôi viết ra đây dể chính các bạn khỏi tẩu hỏa nhập ma.

    Kiến trúc Scalar nếu riêng mình nó cũng chưa chắc đã hoàn hảo. Người Liên Xô trước đây, khi phát triển kiến trúc vô hướng Scalar đã phát triển đồng thời kiến trúc cache. Chính cấu tạo của kiến trúc cache gây khó khăn cho việc sử lý song song.

    Như đã nói, cấu trúc có hướng vector là có duy nhất một bus, tất cả các CPU, RAM... đều cắm vào đó.

    Cấu trúc cache là dữ liệu được lưu trữ trong những vùng lớn và chậm, chuyển dần vào những vùng hẹp và nhanh. Nhờ đó sử lý được khối dữ liệu lớn và nhanh. Các tầng ta thấy như HDD, RAM, L1, L2...Pipeline, thanh ghi. Vì vậy, nhiều người còn gọi Scalar là cái thang do phát âm gần giống scale (chia độ).

    Ta đã biết trong một CPU kể từ 486Dx, CPU đã có nhiều phần tử sử lý song song. Mỗi chuối lệnh đi quan một ống dài, thời gian lệnh đi trong ống khá lâu. Đó là đa phần tử sử lý trong một CPU. Các phần tử này dùng chung một vùng RAM rất nhanh là các thanh ghi và pipe, đây là vùng ram trung tâm, đỉnh cao, nhanh nhất và nhỏ nhất máy.

    Đa CPU là có nhiều đỉnh cao như vậy. Các CPU này chung nhau vùng BUS tốc độ thấp (FSC). Chúng khai thác tài nguyên và dữ liệu ở chân chúng và đưa lên đỉnh chúng nhai nuốt. Khi lên gần đỉnh, chúng bóc thức ăn ra từng phần và cho mỗi phần vào một miệng là các phần tử sử lý, đảm bảo các miệng luôn được ăn tối đa.

    Nhưng cái gì xảy ra khi mỗi đỉnh núi chỉ hút được một luồng lên từ chân núi, nhưng đến lưng chừng thì luồng này lại được tách ra thành rất nhiều luồng con các miệng ăn không xuể. Điều gì xảy ra khi đỉnh bên cạnh lại nhàn rỗi. Cho bớt đỉnh bên cạnh chăng ???? Điều đó không hợp lý vì đi từ dỉnh núi xuống chân núi rồi lại lộn lên bên kia làm chật bus thấp vốn đã chậm. Tất nhiên ai cũng nghĩ đến việc nối hai đỉnh lại, nhưng nối hai đỉnh hay hàng vạn đỉnh là điều từ không hợp lý đến không tưởng: một CPU quá lớn sẽ tăng xác suất hỏng lên theo cấp số nhân.

    Điều này phù hợp với điều tôi đã nói trên, mỗi lệnh đi trong ống khá lay chứ chẳng nhanh gì. Tốc độ chỉ cải thiện khi có nhiều lênh cùng chạy.

    Ví dụ trở lại đoàn ô tô.
    Giả sử hai bãi đất là hai cái cầu có hai đội ô tô đi từ một con đường độc đạo ra. Một cái cầu chật thì các xe trên cầu vẫn phải đi tiếp, quay lại là tắc, đừng nói chuyển sang cầu bên cạnh.
    ----------


    Trước đây tôi đã nói đến nghẹt cache. Đây là hiện tượng như vậy. Các dữ liệu gần nhau được tải vào một lõi dù có vô hướng cũng không đi sang lõi khác được.
    Nhưng tại sao MS Word không nghẹt cache: nó chạy tốt vì nó dược viết bởi nhiều dll, nhiều service liên lạc qua các vùng bộ nhớ dùng chung. Ví dụ, mỗi nút bấm được một dialog gọi nhưng chạy bởi một thư viện khác. Các dialog cũng để trong chương trình rời hay modul trong common.

    Các chương trình rời này được tải mỗi chú vào một lõi không quan hệ, nên MS Word mới chạy tốt vậy.

    Việc chia ra các modul là năng khiếu của người viết chương trình. Tôi nói thế là hiểu phải không ạ.

  6. #36
    Tham gia
    12-02-2007
    Location
    HCM - NT
    Bài viết
    218
    Like
    0
    Thanked 1 Time in 1 Post
    Nếu bạn vẫn không hiểu thì tôi dẫn giải cái sai của bạn nhé. Những học sính mới học lập trình vài ngày rất hay gặp lỗi này: vòng lặp vô tận.

    CPU có thể chọn ra những dãy dữ liệu liên quan và không liên quan, sử lý song song những dãy dữ liệu không liên quan. Đó là cơ chế pipeline, cấu trúc máy kiểu đó là cấu trúc vô hướng scalar.

    Trên nguyên tắc đó, một while ngu ngốc không lối thoát không thể tách ra làm song song nhiều vòng. Vì những lệnh vòng sau, những dữ liệu vòng sau nằm trên chuỗi liên quan vòng trước. Vậy, gặp một vòng while ngu ngốc máy không thể kết thúc event và rơi vào tình trạng nghẹt event: "not responding".

    Bạn đã hiểu rồi chứ. Có lẽ, tôi vẫn chưa tin là bạn hiểu, vì khả năng lập luận của bạn quá kém.
    Xin lỗi vì tôi bị tự ái!
    Bạn chẳng biết 1 cái gì về THREAD mà cứ la cho lớn.

    Kỹ thuật dùng vòng lặp while(1) vô tận là một kỹ thuật mà ngay chính Microsoft cũng phải sử dụng chứ không phải là tôi đưa ra. Bởi vì nó chính là cách để APP để nhận sự kiện, tại sao phải là while (1) bởi vì nó có quá nhiều trường hợp phải thoát, chúng ta không thể kiểm soát hết được những khả năng xảy ra. Chả lẽ phải là

    Code:
    while ( <Bị lỗi 1> ||
            <Bị lỗi 2> ||
            <Bị lỗi 3> ||
            <Bị lỗi 4> ||
            <Bị lỗi 5> || 
            ....
            <Bị lỗi n> || 
    
    }
    Một chương trình trên WINDOWS biết có bao nhiêu lỗi . Hong lẽ phải liệt kê hết khoảng 1000 khả năng lỗi rồi ghi lên đó hả?

    Tôi sẽ cho thấy 1 đoạn code bắt sự kiện nếu lập trình Windows MFC thuần và nó sử dụng một vòng lặp mà bạn cho là "ngu ngốc":

    Code:
    int CMyWinApp::OnRun(){
        MSG msg;
         for (;;){ 
               if (PeekMessage(&msg,NULL,NULL,PM_NOREMOVE)){ // Nhận SỰ KIỆN TỪ WINDOWS
                     if (PumpMessage())
                           return ExitInstance();
               }
               else{
                     // Làm việc nếu ứng dụng ko nhận được sự kiện -> rãnh
               }
          }
          return 1;
    }
    Trên nguyên tắc đó, một while ngu ngốc không lối thoát không thể tách ra làm song song nhiều vòng. Vì những lệnh vòng sau, những dữ liệu vòng sau nằm trên chuỗi liên quan vòng trước. Vậy, gặp một vòng while ngu ngốc máy không thể kết thúc event và rơi vào tình trạng nghẹt event: "not responding".
    Ở đây dang nói chuyện tới WINDOWS, Không biết bạn thử trên HDH nào. Mà ai bảo bạn để while(1) ngay chương trình nền.

    Tôi đã nói là thread, thread,... thread (multithread) cơ mà ông cụ!
    Tại sao lại là thread. Bởi vì nó là một tiến trình xử lý độc lập với chương trình nên việc nó chạy một "while ngu ngốc" cũng chẳng liên quan gì tới tiến trình bắt sự kiện của chương trình chính, "not responding" mà xảy ra thì tôi chuyển nghề khác ngay lập tức. Đó là nguyên tắc để việc các SERVICES (chương trình chạy nền).

    ----------------------------------------------------
    Dẫu sao tôi thấy cái TOPIC này cũng có giá trị. Chúng giúp chúng ta nhận thức ít nhiều đến việc CPU xử lý thế nào trong chương trình?

  7. #37
    Tham gia
    13-08-2005
    Bài viết
    107
    Like
    0
    Thanked 0 Times in 0 Posts
    ôi, trật bản lề hết rồi, không chịu hiểu người khác nói gì, tranh luận nữa cũng chẳng đi tới đâu

  8. #38
    Tham gia
    02-02-2005
    Bài viết
    219
    Like
    0
    Thanked 3 Times in 3 Posts
    eXecutive
    Registered User ngựa non háu đá

    Đấy là hỏi vòng sự kiện. Một phần của thuật In Out (phương pháp hỏi vòng).
    Nó không liên quan gì đến tốc độ ở đây cả.
    Cái vòng ấy có ngu không: co. Bạn ngựa non háu đá bậy biết tại sao không. Nếu cứ như thế, chả ai dùng máy nó cũng chạy đến chết. Nó cứ hỏi hết vòng nàyg đến vòng nọ đến chết, không gì làm nó ra khỏi vòng nếu không có ai động vào.
    Vậy người ta mới phải làm cái time() để cắt cái vòng ngu ngốc của nợ đó, để máy cắt ổ cứng mà monitor tiết kiệm điện, bền. Bạn ngu đến mức không nhận ra cái ngu đó. Cũng là chuyện thường.

    Tôi thấy các bạn càng ngày càng thể hiện trình độ lập trình quá tồi, những người làm tồi như vậy thường rất hay nói mẽ.

    Người ta cũng dừng for hay while, nhưng giữa chừng có một exeption được khởi động, cách này cũng là một cách phục kích tốt. Ví dụ, luôn luôn chia
    b=1;
    a=1;
    c=1;
    try
    c=a/b;
    exction
    .....
    một chuơng trình nào đó đặt b=0 và tạo ra một chuỗi tiến trình.Do tốc dộ nhập sự kiện của người dùng quá chậm so với máy , người ta thêm vào các sleep() để CPU thêm phần nhàn.

    Tóm lại, các ngựa non háu đá nên đọc lại sách và chia chương trình theo modul một cách trong sáng. Không ai sản xuất chip đa nhân để chậm đi cả.

    Học tiếp đi de cỏn. Viết như thế nàu ngu quá:
    Tại sao lại là thread. Bởi vì nó là một tiến trình xử lý độc lập với chương trình
    Tiến trình sử lý độc lập với chương trình thì đem về nhà mà chạy.
    Được sửa bởi huyphuc1981_nb lúc 11:23 ngày 18-09-2007

  9. #39
    Tham gia
    02-02-2005
    Bài viết
    219
    Like
    0
    Thanked 3 Times in 3 Posts
    Quote Được gửi bởi nguyentuan2 View Post
    ôi, trật bản lề hết rồi, không chịu hiểu người khác nói gì, tranh luận nữa cũng chẳng đi tới đâu

    Ờ, tranh luận làm gì, cứ làm theo ý tôi viết hai exe là xong, đỡ phải nghiên cứu và đỡ phải triẻn khai các while thành chuỗi.

    Không ngờ tôi cho các bạn một giải pháp hay nhẩy. Các bạn có thấy đúng là tẩu hỏa nhập ma không.

    Các bạn không tìm dược cách nào chống hiện tượng nghẹt cổ chai chui hết vào một lỗ. Các bạn nghiên cứu rất vất vả ra multi thread.
    Trong khi đó , các tiến sỹ ạ, có một cách hết sức đơn giản là viết 2 exe nếu không muốn hiểu biết về cổ chai.
    Cái cách đó thằng Ms Word và tôi rất ủng hộ. Nhưng nghe chừng mọi người ngại chia modul nhẩy.

    Tôi nhắc lại cơ bản nhất nhé: quá trình lập trình là quá trình mịn hóa, tức là quá trình chia modul càng nhỏ càng tốt.

    Cái này giống lão Newton quá, lão đục một lỗ to và một lỗ bé cho 2 con chui, lão quên rằng con bé chui qua được lỗ to.
    Lão ấy bị táo rụng vào đầu nên mới tẩu hỏa nhập ma như vậy, còn các tiến sỹ, cái gì rơi vào đầu thế.

  10. #40
    Tham gia
    12-02-2007
    Location
    HCM - NT
    Bài viết
    218
    Like
    0
    Thanked 1 Time in 1 Post
    Tôi là một con "ngựa non háu đá". Ok nếu bạn cho là như vậy cũng chả sao nhưng có bao giờ bạn soi gương và bạn thấy bạn là 1 con bò không?
    Đọc hết TOPIC tôi thấy ai bạn cũng cho là ngu hơn bạn. Có lẽ bạn khôn hơn người ta nên trong DDTH này ai cũng là "Resgister User" còn bạn lại là "Thành viên cần được theo dõi".

    Vậy người ta mới phải làm cái time() để cắt cái vòng ngu ngốc của nợ đó, để máy cắt ổ cứng mà monitor tiết kiệm điện, bền. Bạn ngu đến mức không nhận ra cái ngu đó. Cũng là chuyện thường.
    Nếu bạn cho time() (Có lẽ là cái TIMER CONTROL) sử dụng để thay thế while trong thread vậy thì tại sao .NET hay API không bỏ Thread đi, để lại làm gì cho tốn điện.
    Bản chất của time là Thread đặc biệt. Nó sẽ phát ra sự kiện theo chu kỳ lặp theo tick của CPU. Và do đó nó sẽ có khoảng thời gian delay rất lớn.
    Tôi đã thử test TIMER1 (chu kỳ 300 milisecond) hoàn toàn chạy bằng với TIMER2 (chu kỳ 100 milisecond). Người ta chỉ dùng TIMER để viết các hàm như cập nhật tin tức trong vòng 30 giây, hoặc là giới hạn thời gian đăng nhập, login là n giây... chứ chả thấy ai sử dụng để xử lý bài toán song song...
    Dĩ nhiên THREAD phải có những cái hơn hẳn TIMER là xử lý nhanh nhưng không cần thời gian chờ DELAY.
    Không hiểu bạn nghĩ sao mà nói rằng dùng TIMER để tiết kiệm điện. Có bao giờ ngồi quét virus mà tự chửi máy tính "sao mày quét lâu thế không?" Nếu nó mà tiết kiệm điện cho bạn bằng cách sử dụng timer hay delay thì không biết như thế nào... (thông minh thì tự hiểu)

    Các bạn không tìm dược cách nào chống hiện tượng nghẹt cổ chai chui hết vào một lỗ. Các bạn nghiên cứu rất vất vả ra multi thread.
    Trong khi đó , các tiến sỹ ạ, có một cách hết sức đơn giản là viết 2 exe nếu không muốn hiểu biết về cổ chai.
    Cái cách đó thằng Ms Word và tôi rất ủng hộ. Nhưng nghe chừng mọi người ngại chia modul nhẩy.

    Tôi nhắc lại cơ bản nhất nhé: quá trình lập trình là quá trình mịn hóa, tức là quá trình chia modul càng nhỏ càng tốt.
    Khùng hết cỡ!
    Viết chia modul trong chtr là việc phải làm. Tưởng chúng tôi lập trình NGÔN NGỮ MÁY hả.
    Nhưng vấn để là để triển khai 2 MODUL thực hiện 1 lúc (gần như là cùng 1 thời điểm) không ngoài MULTITHREAD còn cách này hiệu quả hơn nữa không?

    Bạn nói CPU chạy 100% bị "thắt cổ chai". Thắt cổ chai là thế nào? Nó là một thuật ngữ của MẠNG. Tức là khi 1 SEVER nhận dữ liệu ở mức quá tải trong khi BĂNG THÔNG đường truyền có giới hạn, làm hệ thống mạng đó bị nghẽn đường truyền.
    Còn ở đây là 1 bài toán ở CLIENT. Việc CPU chạy ở 100% là chuyện bình thường mà thôi chẳng có thắt cỗ chai ở đâu ra. Tôi quét VIRUS trong vòng 1 tiếng CPU vẫn chạy 100% có bốc khói đâu?
    Được sửa bởi eXecutive lúc 12:19 ngày 18-09-2007

Trang 4 / 6 FirstFirst 123456 LastLast

Bookmarks

Quy định

  • Bạn không thể tạo chủ đề mới
  • Bạn không thể trả lời bài viết
  • Bạn không thể gửi file đính kèm
  • Bạn không thể sửa bài viết của mình
  •