我正在测试使用OpenMP时某些算法的性能加速,其中一个算法没有缩放.难道我做错了什么?
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>
int main(int argc, char **argv) {
int test_size, i;
double *vector, mean, stddeviation, start_time, duration;
if (argc != 2) {
printf("Usage: %s <test_size>\n", argv[0]);
return 1;
}
srand((int) omp_get_wtime());
test_size = atoi(argv[1]);
printf("Test Size: %d\n", test_size);
vector = (double *) malloc(test_size * sizeof(double));
for (i = 0; i < test_size; i++) {
vector[i] = rand();
}
start_time = omp_get_wtime();
mean = 0;
stddeviation = 0;
#pragma omp parallel default(shared) private(i)
{
#pragma omp for reduction(+:mean)
for (i = 0; i < test_size; i++) {
mean += vector[i];
}
#pragma omp single
mean /= test_size;
#pragma omp for reduction(+:stddeviation)
for (i = 0; i < test_size; i++) {
stddeviation += (vector[i] - mean)*(vector[i] - mean);
}
}
stddeviation = sqrt(stddeviation / test_size);
duration = omp_get_wtime() - start_time;
printf("Std. Deviation = %lf\n", stddeviation);
printf("Duration: %fms\n", duration*1000);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
gcc -c -o main.o main.c -fopenmp -lm -O3
gcc -o dp main.o -fopenmp -lm -O3
Run Code Online (Sandbox Code Playgroud)
$ OMP_NUM_THREADS=1 ./dp 100000000
166.224199ms
$ OMP_NUM_THREADS=2 ./dp 100000000
157.924034ms
$ OMP_NUM_THREADS=4 ./dp 100000000
159.056189ms
Run Code Online (Sandbox Code Playgroud)
我不会使用 Ubuntu 14.04.2 LTS、gcc 4.8 和 2.3 GHz Intel Core i7 重现您的结果。以下是我得到的结果:
\n\n\n$ OMP_NUM_THREADS=1 ./so30627170 100000000\n测试大小:100000000\n标准。偏差 = 619920018.463329\n持续时间:206.301721ms\n$ OMP_NUM_THREADS=2 ./so30627170 100000000\n测试大小:100000000\n标准。偏差 = 619901821.463117\n持续时间:110.381279ms\n$ OMP_NUM_THREADS=4 ./so30627170 100000000\n测试大小:100000000\n标准。偏差 = 619883614.594906\n持续时间: 78.241708ms\n\n\n
由于问题的“结果”部分中列出的输出与列出的代码的输出不匹配,因此您可能正在运行旧版本的代码。
\n\n我考虑过可能在并行for循环中使用 X86 内在函数,但检查汇编输出,在这种情况下 gcc 已经使用了 SIMD 指令。如果没有 March 选项,我看到 gcc 使用 SSE2 指令。使用-march=native或进行编译-mavx,gcc 将使用 AVX 指令。
编辑:运行程序的 Go 版本,我得到:
\n\n\n$ ./tcc-go-desvio-padrao -w 1 -n 15 -t 100000000\n2015/06/07 08:26:43 工人:1\n2015/06/07 08:26:43 测试:[100000000 ]\n2015/06/07 08:26:43 每个测试的执行次数:15\n2015/06/07 08:26:43 分配内存的时间:584.477\xc2\xb5s\n2015/06/07 08:26 :43 ===========================================\n2015/06/ 07 08:26:43 当前测试大小:100000000\n2015/06/07 08:27:05 填充数组的时间:1.322556083s\n2015/06/07 08:27:05 计算时间:194.10728ms\n$ ./tcc-go-desvio-padrao -w 2 -n 15 -t 100000000\n2015/06/07 08:27:10 工作人员:2\n2015/06/07 08:27:10 测试:[100000000]\n2015 /06/07 08:27:10 每个测试的执行次数:15\n2015/06/07 08:27:10 分配内存的时间:565.273\xc2\xb5s\n2015/06/07 08:27:10 = ==========================================\n2015/06/07 08: 27:10 当前测试大小:100000000\n2015/06/07 08:27:22 填充数组的时间:677.755324ms\n2015/06/07 08:27:22 计算时间:113.095753ms\n$ ./tcc -go-desvio-padrao -w 4 -n 15 -t 100000000\n2015/06/07 08:27:28 工作人员:4\n2015/06/07 08:27:28 测试:[100000000]\n2015/06/ 07 08:27:28 每个测试的执行次数:15\n2015/06/07 08:27:28 分配内存的时间:576.568\xc2\xb5s\n2015/06/07 08:27:28 ==== ======================================\n2015/06/07 08:27:28当前测试大小: 100000000\n2015/06/07 08:27:34 填充数组的时间: 353.646193ms\n2015/06/07 08:27:34 计算时间: 79.86221ms\n\n\n
时间显示与 OpenMP 版本大致相同。
\n