RP Store Tìm linh kiện theo mã, gửi BOM nhận báo giá Gửi BOM

Thời gian thực hiện tính toán của PIC32

Collapse
X
 
  • Giờ
  • Show
Clear All
new posts
  • ngocthanh07
    Đệ tử 2 túi
    • Mar 2007
    • 42

    #1

    Thời gian thực hiện tính toán của PIC32

    Mình dùng MPLAB C32 viết chuơng trình thử PIC32,

    Dùng vòng lập thử tính hàm atan2(x,y) 10000 lần, lấy đồng hồ bấm giây đo thời gian thực hiện. kết quả cho thấy nó mất 11 giây để thực hiện

    ==>một hàm atan2 phải mất 1.1 ms để thực hiện

    Giả sử PIC chạy 72 MHz, suy ra 1 chu kì là 1/72Mhz (s)
    ==> 1.1ms thực hiện đuợc 1.1 ms / (1/72Mhz) chu kì

    kết quả là 79200 chu kì

    Có nghĩa là vi xử lí thực hiện một lệnh atan2 mất 79200 chu kì máy, kết quả này có vẻ không hợp lí lắm


    Mình muốn hỏi cách thực hiện dịch tối ưu lệnh trên MPLAB C 32 và cách cấu hình để PIC chạy ở tốc độ nhanh nhất

    Cảm ơn
  • namqn
    Trưởng lão PIC bang
    • Feb 2006
    • 3020

    #2
    Lâu rồi tôi quên mất post này. Hôm nay xem lại, tôi đã thử nghiệm với MPLAB C32 v1.02 và C32 v1.04.

    Với MPLAB C32 v1.02 SE, tôi chỉ dùng được hàm atan2() với đối số và kết quả là các số double. Số chu kỳ cần thiết khi thực thi hàm vào khoảng 6000 - 8000 chu kỳ máy (mô phỏng bằng MPLAB SIM).

    Với MPLAB C32 v1.04 còn đang trong giai đoạn evaluation, tôi có thể dùng các hàm atan2() và atan2f() (atan2f() có đối số và kết quả là các số float). Số chu kỳ cần thiết khi thực thi hàm atan2() là vào khoảng 700 - 900 chu kỳ máy, còn hàm atan2f() mất khoảng hơn 200 chu kỳ máy (cũng mô phỏng bằng MPLAB SIM). Chú ý sự cải thiện rất đáng kể của thư viện đi kèm v1.04!

    Do đó, để đạt được tốc độ tính toán cao với các PIC32, nên dùng phiên bản mới nhất của trình biên dịch MPLAB C32.

    Thân,
    Biển học mênh mông, sức người có hạn.

    Đang gặp vấn đề cần được giúp đỡ? Hãy dành ra vài phút đọc luồng sau:
    http://www.picvietnam.com/forum/showthread.php?t=1263

    Comment

    • ngocthanh07
      Đệ tử 2 túi
      • Mar 2007
      • 42

      #3
      Hôm nay em mới có dịp quay lại bài này.

      Hôm qua em lôi cái mạch Pic32 Starter Kit ra thử có vài thắc mắc,
      Đoạn code mà em thử như sau (copy từ trên microchip forum và vài chỗ khác)
      Em dùng MPLAB 8.36, C32 V1.05 , Optimize level -O3
      Code:
      #include <p32xxxx.h>
      #include <plib.h>
      
      #pragma config FPLLMUL = MUL_20, FPLLIDIV = DIV_2, FPLLODIV = DIV_1
      #pragma config POSCMOD = HS, FNOSC = PRIPLL
      #pragma config FPBDIV = DIV_1
      #pragma config FCKSM = CSECMD
      #pragma config IESO = ON
      #pragma config FWDTEN = OFF
      
      int t,t1,t2;
      extern unsigned int __attribute__((section(".math_errhandling")))math_errhandling;
      
      int main(void)
      { 
         SYSTEMConfigPerformance(40000000) ;
         mCheConfigure(CHE_CONF_WS2       |
                       CHE_CONF_PF_ALL    |
                       CHE_CONF_DC_NONE   |
                       CHE_CONF_COH_INVUNL
                       );
         CheKseg0CacheOn();
         mBMXDisableDRMWaitState();
         //math_errhandling = 0;
      
      // init 32-bit timer4/5
      OpenTimer45(T4_ON | T4_SOURCE_INT, 0);
      PR5 = 0xFFFFFFFF;
      PR4 = 0xFFFFFFFF;
      
      // clear the 32-bit timer count
      WriteTimer45(0);
      
      	int InitTime =  ReadTimer45();
        /* initialize constants */
      
        t   =   0.499975;
        t1  =   0.50025;
        t2  =   2.0;
      
      	int ResultTime = ReadTimer45();
          int Cal_Time   = ResultTime - InitTime;
      	return ResultTime;
         
      }
      Sử dụng PIC32 Starterkit làm debugger và quan sát TMR4 - TMR5, em đặt brakpoints tại hàng
      Code:
       int InitTime =  ReadTimer45();
      và sau đó chạy step over từng lệnh
      Kết quả quang sát các giá trị như sau
      Code:
      				                 TMR4		TMR5
      
      int InitTime =  ReadTimer45(); 	0x00F2_8C66	0x0000_0103
      t   =   0.499975;			        0x9D22_9090	0x0000_9D33
       t1  =   0.50025;			        0xB9B7_16B0	0x0000_B9C8
      t2  =   2.0;				        0x70C8_18CD	0x0000_70D9
      int ResultTime = ReadTimer45();  0xE9C2_AD21	0x0000_E9D2
      return ResultTime;			0X2A20_E3F6	0x0000_2A31
      
      InitTime			0x9C41_0455
      ResultTime		        0x2939_162D
      Nếu như theo kết quả này thì thời gian thực hiện từng lệnh là quá lâu,
      chỉ thực hiện 3 lệnh gán mà có vẽ như Timer45 (32 bit) đã tăng từ 0x9C41_0455 đến 0xFFFF_FFFF để tràn rồi đếm tiếp đến 0x2939_162D, sơ sỡ đã thấy nhiều hơn 0X6000_0000 chu kì, con số này lớn lắm, khoảng 1.5 tỉ lận !!!!

      Có cái gì đó không hợp lí, mong các bạn và anh Nam chỉ giúp
      Mình up kèm mấy cái hình khi chạy
      Còn dưới đây là file De-ASM của đoạn code mình thử
      Code:
      27:                  OpenTimer45(T4_ON | T4_SOURCE_INT, 0);
      9D0004D8  3C02BF80   lui         v0,0xbf80
      9D0004DC  AC400C10   sw          zero,3088(v0)
      9D0004E0  3C02BF80   lui         v0,0xbf80
      9D0004E4  AC400C10   sw          zero,3088(v0)
      9D0004E8  3C02BF80   lui         v0,0xbf80
      9D0004EC  AC400C20   sw          zero,3104(v0)
      9D0004F0  3C03BF80   lui         v1,0xbf80
      9D0004F4  34028008   ori         v0,zero,0x8008
      9D0004F8  AC620C00   sw          v0,3072(v1)
      28:                  PR5 = 0xFFFFFFFF;
      9D0004FC  3C03BF80   lui         v1,0xbf80
      9D000500  2402FFFF   addiu       v0,zero,-1
      9D000504  AC620E20   sw          v0,3616(v1)
      29:                  PR4 = 0xFFFFFFFF;
      9D000508  3C03BF80   lui         v1,0xbf80
      9D00050C  2402FFFF   addiu       v0,zero,-1
      9D000510  AC620C20   sw          v0,3104(v1)
      30:                  
      31:                  // clear the 32-bit timer count
      32:                  WriteTimer45(0);
      9D000514  3C02BF80   lui         v0,0xbf80
      9D000518  AC400C10   sw          zero,3088(v0)
      33:                  
      34:                  	int InitTime =  ReadTimer45();
      9D00051C  3C02BF80   lui         v0,0xbf80
      9D000520  8C420C10   lw          v0,3088(v0)
      9D000524  AFC2005C   sw          v0,92(s8)
      35:                    /* initialize constants */
      36:                  
      37:                    t   =   0.499975;
      9D000528  AF80800C   sw          zero,-32756(gp)
      38:                    t1  =   0.50025;
      9D00052C  AF808014   sw          zero,-32748(gp)
      39:                    t2  =   2.0;
      9D000530  24020002   addiu       v0,zero,2
      9D000534  AF828010   sw          v0,-32752(gp)
      40:                  
      41:                  	int ResultTime = ReadTimer45();
      9D000538  3C02BF80   lui         v0,0xbf80
      9D00053C  8C420C10   lw          v0,3088(v0)
      9D000540  AFC20058   sw          v0,88(s8)
      42:                      int Cal_Time   = ResultTime - InitTime;
      9D000544  8FC30058   lw          v1,88(s8)
      9D000548  8FC2005C   lw          v0,92(s8)
      9D00054C  00621023   subu        v0,v1,v0
      9D000550  AFC20054   sw          v0,84(s8)
      43:                  	return ResultTime;
      9D000554  8FC20058   lw          v0,88(s8)
      44:                     
      45:                  }
      9D000558  03C0E821   addu        sp,s8,zero
      9D00055C  8FBF0064   lw          ra,100(sp)
      9D000560  8FBE0060   lw          s8,96(sp)
      9D000564  27BD0068   addiu       sp,sp,104
      9D000568  03E00008   jr          ra
      9D00056C  00000000   nop
      Attached Files
      Last edited by ngocthanh07; 21-08-2009, 10:24 AM.

      Comment

      • bien_van_khat
        ...Damned...
        • Apr 2006
        • 503

        #4
        Khi bạn dùng step over, timer có thể không bị freeze, do đó, khi CPU dừng thì timer vẫn chạy. Trong thời gian debugger cập nhật dữ liệu, thì timer đã thay đổi rất nhiều!

        Thực chất bạn đang muốn kiểm tra điều gì?
        - Xin đọc trước khi post bài

        Xin đặt code trong thẻ [ code ] [ /code ]

        Comment

        • ngocthanh07
          Đệ tử 2 túi
          • Mar 2007
          • 42

          #5
          Mình muốn kiểmm tra số chu kì máy thực hiện cho từng dòng lệnh.

          Nếu muốn làm vậy, ngoài cách dùng Timer còn có cách nào không?

          Comment

          • bien_van_khat
            ...Damned...
            • Apr 2006
            • 503

            #6
            Để kiểm tra số chu kỳ máy đối với 1 đoạn chương trình, cách đơn giản nhất là dùng MPLAB SIM, và kiểm tra bằng stopwatch

            Tuy nhiên với PIC32 thì phương pháp này không hoàn toàn chính xác vì có Flash wait state đối với các lệnh rẽ nhánh. CPU có thể phải chờ flash khi gặp các lệnh gọi hàm, lệnh nhảy.

            Nếu bạn muốn tính thời gian thực thi 1 lệnh có thể viết 1 đoạn assembly để bật tắt 1 chân IO, rồi dùng oscilloscope để kiểm tra chu kỳ của tín hiệu ra.

            Chú ý: nếu dùng phương pháp bật tắt IO bạn phải sử dụng các thanh ghi dùng riêng để set và clear bit.
            - Xin đọc trước khi post bài

            Xin đặt code trong thẻ [ code ] [ /code ]

            Comment

            • herrtien
              Banned
              • Nov 2006
              • 107

              #7
              PIC32 có thời gian xử lý toán rất nhanh. Các bạn cứ yên tâm như vậy, vì tôi đã làm thiết bị liên quan đến vấn đề này rồi. http://www.youtube.com/watch?v=GetUORbRX-U

              Comment

              • ngocthanh07
                Đệ tử 2 túi
                • Mar 2007
                • 42

                #8
                Rất nhanh nhưng cũng có giới hạn chứ, mình chỉ muốn biết nó nhanh cỡ nào và có đáng để đổi từ dsPIC sang PIC32 không chẳng hạn. Nếu mình vọc chơi thì cần gì nhanh chậm gì cả, mình muốn nghiên cứu cụ thể, vậy thì phải có thống kê ...thống kê thì cần có số liệu ....
                Mình muốn đến cuối cùng nhìn một đoạn chương trình C của PIC32 có thể tính phỏng đoán được nó thực hiện mất bao nhiêu giây

                Comment

                Working...