Viet Dev

Tuan for Unicloud Group

Posted on

Tính số Fibonacci với 2-core ESP32

Mục đích của thử nghiệm này để thấy rõ sự khác biệt khi thực thi tác vụ dựa trên 1 core và 2 core CPU, không có ý định giải quyết các vấn đề toán học cũng như phân tải, chia luồng.

Với ESP-IDF dựa trên trên FreeRTOS là RTOS cho chip ESP32 với rất hạn chế về tài nguyên bộ nhớ, chỉ cần tầm vài chục KB RAM là chạy được. Chính vì thế việc thực nghiệm đa luồng, đa nhân trên FreeRTOS khá dễ hiểu và ít sự phức tạp như khi làm trên các hệ điều hành như Linux.

Về cơ bản, bài viết ở đây đã nói rõ chi tiết rồi, còn bài viết này chỉ hướng dẫn làm sao để chạy được đồng bộ hoá trên 2 nhân.

Vì Fn = F(n-1) + F(n-2), nên cách đơn giản nhất là cứ chia ra, F(n-1) cho core 1 xử lý, còn F(n-2) cho thằng core 2 xử lý. Core1 làm nhiều hơn core2 một chút.

Hàm tính Fibonacci như sau:

int fib(int n)
{
    if (n < 2) return n;
    else {
        int x = fib(n - 1);
        int y = fib(n - 2);
        return x + y;
    }
}
Enter fullscreen mode Exit fullscreen mode

Để test với 2 nhân thì cần đồng bộ hóa 2 task chạy trên 2 nhân, với FreeRTOS thì task notify sẽ có hiệu suất cao hơn, nhưng giai đoạn này bản esp-idf chưa hoàn thiện và task notify chưa hoạt động, do đó Binary Semaphore là lựa chọn lúc này. Task dành cho Core1 sau khi thực thi xong sẽ Give Semaphore, và tự hủy. Task dành cho Core0 sau khi tính toán xong thì đợi Semaphore rồi lấy tổng. Mục đích là test performance nên không quan tâm tới kết quả test.

void core1_task(void *ptr)
{
    int i = ((thread_args *) ptr)->input;
    ((thread_args *) ptr)->output = fib(i);
    xSemaphoreGive(xSemaphore);
    vTaskDelete(NULL);
}

 int test_dual_core(int num)
{
    thread_args args;
    int start, end, f;

    start = xTaskGetTickCount();

    args.input = num - 1;
    xTaskCreatePinnedToCore(core1_task, "core1", 10*1024, &args, 10, NULL, 1);
    f = fib(num - 2);
    xSemaphoreTake(xSemaphore, portMAX_DELAY);
    f += args.output;
    end = xTaskGetTickCount();
    return end - start;
}
Enter fullscreen mode Exit fullscreen mode

Kết quả test khá ấn tượng, ratio hơn 1.65. Nếu làm trên máy tính tầm 1.5 thôi — có lẽ nhiều overhead cho các tác vụ hệ điều hành.

espfibo

Link toàn bộ dự án, biên dịch cho ESP32:
https://github.com/tuanpmt/esp-fibonacci-dualcore-test/blob/master/main/main.c

Top comments (1)

Collapse
 
tieutuanbao profile image
Tiêu Tuấn Bảo

Hi anh! Anh có thể làm bài hướng dẫn DMA với SPI dùng Linked-List được không ạ? Em đang cấu hình chưa chạy được ạ.