30/09/2018, 18:26

[ QT ] Khắc phục hiệu năng thấp của ứng dụng build bằng QT

Mình đang sử dụng QT cho một số bài toán cần hiệu năng tuy nhiên những gì mình thu được là không thỏa mãn. QT build ra App có hiệu năng khá thấp.


Mình có 1 mảng unsigned char gồm 200.000.000 phần tử, mình sẽ tăng giá trị các phần tử lên 1 bằng 1 vòng for và thực hiện 50 lần. Thời gian thực hiện sẽ được in ra màn hình.

Với QT 5.5 Windows 32 + MINGW 4.9(C++) :

QElapsedTimer tmr;
unsigned char *arr = new unsigned char[200000000];

qint64 proctime=0;

int main() {
    while(true) {
        proctime=0;
        for(int loop=0; loop<50; loop++) {
            tmr.restart();
            for(int i=0; i<200000000; i++)
                arr[i]++;
            proctime+=tmr.elapsed();
        }
        printf("%d
",proctime);
    }
    return 0;
}

Trong CSharp (thuần C#) :

static Stopwatch st = new Stopwatch();
static byte[] arr = new byte[200000000];
static long proctime = 0;
static unsafe void Main(string[] args) {
    fixed (byte* ptr = arr) {
        while (true) {
            proctime = 0;
            for (int loop = 0; loop < 50; loop++) {
                st.Restart();
                for (int i = 0; i < 200000000; i++)
                    ptr[i]++;
                proctime += st.ElapsedMilliseconds;
            }
            Console.WriteLine(proctime.ToString());
        }
    }
}

Và CSharp kết hợp C++: (CSharp gọi hàm xử lý trong 1 dll build bằng C++ MSVC)

static Stopwatch st = new Stopwatch();
static byte[] arr = new byte[200000000];

static long proctime = 0;

[DllImport("DLL.dll")]
extern static void ProcCess(IntPtr ptr, int num);


static unsafe void Main(string[] args) {
    fixed (byte* ptr = arr) {
        while (true) {
            proctime = 0;
            for (int loop = 0; loop < 50; loop++) {
                st.Restart();
                ProcCess((IntPtr)ptr, 200000000);
                proctime += st.ElapsedMilliseconds;
            }
            Console.WriteLine(proctime.ToString());
        }
    }
}

Đây là code của DLL C++:

extern "C"
{
    __declspec(dllexport) void __stdcall ProcCess(unsigned char *ptr,int num) {
        for (int i = 0; i < num; i++)
            ptr[i]++;
    }
}

Phần cứng : Core i3 4160 3.6GHz Windows7
Chế độ test : SafeMode.
Chế độ build 3 App : 32bit, Release


Kết quả:
QT nhanh hơn thuần CSharp 1 chút (10/8).
CSharp+ dll C++ nhanh nhất. Gấp gần 3 lần CSharp và QT.


Vậy vấn đề app của QT chậm chạp ở đây là gì. Làm thế nào mình khắc phục được.
Xin cảm ơn !

Mai Anh Dũng viết 20:32 ngày 30/09/2018

Wow, cảm ơn @Duong_Act đã đưa ra một vấn đề rất thú vị.

Bạn thử chạy code Qt và sử dụng DLL thử? Xem thử kết quả như thế nào.

Trong đoạn code của bạn sử dụng extern "C" nên code này giống C hơn là C++. Tuy nhiên Đạt không nghĩ là có sự khác nhau gì nhiều.

extern "C"
{
    __declspec(dllexport) void __stdcall ProcCess(unsigned char *ptr,int num) {
        for (int i = 0; i < num; i++)
            ptr[i]++;
    }
}

Bạn thử lấy code Qt rồi gọi DLL này xem kết quả như thế nào?

Văn Dương viết 20:35 ngày 30/09/2018

Chào @ltd Đạt !
Cảm ơn bạn đã đọc và reply nhanh.
Mình vẫn chưa biết cách gọi hàm trong 1 dll có sẵn vào QT như thế nào (mình mới bắt đầu với QT một thời gian ngắn).
Bạn có thể chỉ cách cho mình không ?
Cảm ơn bạn !

Mai Anh Dũng viết 20:35 ngày 30/09/2018

Qt bản chất là C++, đặc biệt là trong đoạn code Qt bạn cũng không sử dụng tính năng gì đặc biệt của Qt ngoại trừ QElapsedTimer, việc này không ảnh hưởng gì đến tốc độ tính toán của chương trình.

Nên Đạt nghĩ vấn đề nằm ở chỗ loop.


Mình vẫn chưa biết cách gọi hàm trong 1 dll có sẵn vào QT như thế nào (mình mới bắt đầu với QT một thời gian ngắn).

Tương tự, Qt là C++, load DLL trên Qt tức là load DLL trên C++. Bạn đang dùng Visual Studio hay QtCreator? Bạn có thể google để biết cách sử dụng DLL với từng Editor khác nhau.

Văn Dương viết 20:35 ngày 30/09/2018

Hi Đạt !

Qt bản chất là C++, đặc biệt là trong đoạn code Qt bạn cũng không sử dụng tính năng gì đặc biệt của Qt ngoại trừ QElapsedTimer, việc này không ảnh hưởng gì đến tốc độ tính toán của chương trình.

Nên Đạt nghĩ vấn đề nằm ở chỗ loop.

Mình cũng nghĩ vậy. Ở đây mình không dùng gì đặc biệt cả. Chỉ là vòng lặp for thông thường, phép toán + và con trỏ thôi. Lẽ ra như vậy nó phải đạt được hiệu năng cao nhất nhưng thực tế nó chỉ nhỉnh hơn C# thuần một chút tức là khá chậm.

Mình đang sử dụng QT Creator 5.5 (có tích hợp sẵn MINGW 4.9 32bit).
Mình cũng google nhưng vẫn chưa thành công. Vẫn chưa sử dụng được hàm trong dll.

Tran Huan viết 20:39 ngày 30/09/2018

Có nhầm không, trên máy Core i5 mình chạy tới 23 seconds lận (with Qt). Coi chừng compiler optimize, DLL build bằng compiler gì vậy? bạn có kiểm tra lại kết quả của mảng sau khi gọi hàm Process chưa?

PS: Đã test thêm trên application project không có Qt tốc độ chỉ 5 seconds (so strange!), có lẽ có một cờ nào đó trên compiler ảnh hưởng tới code được build

Văn Dương viết 20:36 ngày 30/09/2018

Hi @tranhuanltv
DLL mình build bằng MSVC (viết bằng Win32 trong Visual Studio).
Đã có kiểm tra lại kết quả của mảng rồi đó bạn.
Bạn build ở chế độ release rồi chạy trực tiếp không qua QT xem thế nào.

Complier của QT mình để mặc định. Mình có search là thay đổi optimize -O2,-O3 gì đó nhưng đã thử và không thấy thay đổi gì bạn ạ.

Văn Dương viết 20:27 ngày 30/09/2018

Up up up up up up up
Các bạn còn đó không ?

Mai Anh Dũng viết 20:34 ngày 30/09/2018

Kiểu này chắc phải raise issue lên bên Qt nhờ họ giúp

Văn Dương viết 20:31 ngày 30/09/2018

Vậy hiệu năng của các App build bằng QT của các bạn trên Windows thì thế nào vậy ?

Mai Anh Dũng viết 20:31 ngày 30/09/2018

Mình thấy bình thường, không đến nỗi quá chậm như trong trường hợp của bạn.

Văn Dương viết 20:27 ngày 30/09/2018

Không ý mình là với bài test như của mình.
Chứ nếu App thông thường thì khó nhận biết được.

viết 20:35 ngày 30/09/2018

của ta chạy tốc độ như nhau mà?

chắc là do Qt trên Windows ko hợp với MinGW cho lắm. Cái này là Qt của msvc2013 32 bit.

Văn Dương viết 20:33 ngày 30/09/2018

Cảm ơn bạn !
Không biết có phải như bạn nói là do MINGW không.
Mình cũng thử với DevC++ MINGW còn cho kết quả thảm hại hơn nữa ( Còn chậm hơn cả C#).

Văn Dương viết 20:34 ngày 30/09/2018

Cuối cùng thì mình tải Qt MSVC 5.5.1.
Build xong chạy có 2000ms. Chắc do MINGW.

Mai Anh Dũng viết 20:35 ngày 30/09/2018

Lạ hen, code giống nhau hết hả @Duong_Act?

Văn Dương viết 20:36 ngày 30/09/2018

Giống y đúc nhau luôn bạn ạ

Bài liên quan
0