OK, tôi đã nói chuyện với một người bạn về các trình biên dịch và tối ưu hóa các chương trình, và ông đề nghị rằng n * 0.5
nhanh hơn n/2
. Tôi đã nói rằng trình biên dịch thực hiện điều đó loại tối ưu hóa tự động, vì vậy tôi đã viết một chương trình nhỏ để xem nếu có một sự khác biệt giữa n/2
và n * 0.5
:1.000.000.000 phép tính trên mỗi micro giây?
Division:
#include <stdio.h>
#include <time.h>
int main(int argc, const char * argv[]) {
int i, m;
float n, s;
clock_t t;
m = 1000000000;
t = clock();
for(i = 0; i < m; i++) {
n = i/2;
}
s = (float)(clock() - t)/CLOCKS_PER_SEC;
printf("n = i/2: %d calculations took %f seconds (last calculation = %f)\n", m, s, n);
return 0;
}
Nhân:
#include <stdio.h>
#include <time.h>
int main(int argc, const char * argv[]) {
int i, m;
float n, s;
clock_t t;
m = 1000000000;
t = clock();
for(i = 0; i < m; i++) {
n = i * 0.5;
}
s = (float)(clock() - t)/CLOCKS_PER_SEC;
printf("n = i * 0.5: %d calculations took %f seconds (last calculation = %f)\n", m, s, n);
return 0;
}
Và cho cả hai phiên bản, tôi nhận được 0.000002s avg. khi được biên soạn với clang main.c -O1
. Và anh ta nói phải có điều gì đó sai trái với phép đo thời gian. Vì vậy, sau đó ông đã viết một chương trình:
#include <cstdio>
#include <iostream>
#include <ctime>
using namespace std;
int main()
{
clock_t ts, te;
double dT;
int i, m;
double n, o, p, q, r, s;
m = 1000000000;
cout << "Independent calculations:\n";
ts = clock();
for (i = 0; i < m; i++)
{
// make it a trivial pure float calculation with no int casting to float
n = 11.1/2.3;
o = 22.2/2.3;
p = 33.3/2.3;
q = 44.4/2.3;
r = 55.5/2.3;
s = 66.6/2.3;
}
te = clock();
dT = ((float)(te - ts))/CLOCKS_PER_SEC; // make initial call to get the elapsed time to run the loop
ts = clock();
printf("Division: %d calculations took %f seconds\n", m, dT);
for (i = 0; i < m; i++)
{
// make it a trivial pure float calculation with no int casting to float
n = 11.1 * 0.53;
o = 22.2 * 0.53;
p = 33.3 * 0.53;
q = 44.4 * 0.53;
r = 55.5 * 0.53;
s = 66.6 * 0.53;
}
te = clock();
dT = ((float)(te - ts))/CLOCKS_PER_SEC; // make initial call to get the elapsed time to run the loop
ts = clock();
printf("Multiplication: %d calculations took %f seconds\n", m, dT);
cout << "\nDependent calculations:\n";
for (i = 0; i < m; i++)
{
// make it a trivial pure float calculation with no int casting to float
n = 11.1/2.3;
o = n/2.3;
p = o/2.3;
q = p/2.3;
r = q/2.3;
s = r/2.3;
}
te = clock();
dT = ((float)(te - ts))/CLOCKS_PER_SEC; // make initial call to get the elapsed time to run the loop
ts = clock();
printf("Division: %d calculations took %f seconds\n", m, dT);
for (i = 0; i < m; i++)
{
// make it a trivial pure float calculation with no int casting to float
n = 11.1 * 0.53;
o = n * 0.53;
p = o * 0.53;
q = p * 0.53;
r = q * 0.53;
s = r * 0.53;
}
te = clock();
dT = ((float)(te - ts))/CLOCKS_PER_SEC; // make initial call to get the elapsed time to run the loop
ts = clock();
printf("Multiplication: %d calculations took %f seconds\n", m, dT);
return 0;
}
Và cho rằng ông đã ...
1.869570s
1.868254s
25.674016s
3.497555s
... theo thứ tự đó.
Vì vậy, tôi đã chạy chương trình trên máy của mình được biên dịch với clang++ main.cpp -O1
và tôi nhận được kết quả tương tự như trước: 0.000002 to 0.000011
.
Tuy nhiên, khi tôi biên soạn chương trình mà không tối ưu hóa, tôi nhận được kết quả tương tự cho anh ta trong bài kiểm tra đầu tiên của mình. Vì vậy, câu hỏi của tôi là, làm thế nào có thể bất kỳ số lượng tối ưu hóa làm cho chương trình rằng nhanh hơn nhiều?
do đó, có một số vấn đề nghiêm trọng với chương trình điểm chuẩn của bạn. Điều đó sẽ phá vỡ bất cứ điều gì bạn đang cố gắng để kiểm tra anyway. Đáng chú ý nhất là bạn đang pha trộn các loại và có loại coersion xảy ra đó là rất đắt tiền và của chính nó (và có thể là những gì bạn của bạn đang đề cập đến). Ngoài ra không có gì ở đây một trình biên dịch không thể tính toán tại thời gian biên dịch. – Mgetz
'n = i * 0.5;' kích hoạt 'i' thành' double', bội số bằng 0,5 và chuyển về 'float'. 'n = i/2;' phân chia (có thể thay đổi) 'i' bằng 2, sau đó chuyển thành gấp đôi. Bạn không thử nghiệm nhân với phân chia, nhưng hoạt động không liên quan. –
Nếu bạn muốn "điểm chuẩn" không được tối ưu hóa, hãy thử tích luỹ kết quả trong mỗi lần lặp trong biến 's'. Sau đó in giá trị cuối cùng của 's' sau khi bạn đã thực hiện phép tính thời gian. – Praetorian