OpenMP出现Stack Overflow及其疑问
今天对着《OpenMP核心技术指南》练习OpenMP,其中一个案例:
#include <stdio.h>
#include <math.h>
#include <omp.h>#define ITER 100000000void main()
{int i;double A[ITER];for (i = 0; i < ITER; i++)A[i] = 2.0 * i;#pragma omp parallel{// int i;int id = omp_get_thread_num();double todata = omp_get_wtime();#pragma omp for schedule(static)for (i = 1; i < ITER; i++)A[i] = A[i] * sqrt(i) / pow(sin(i), tan(i));todata = omp_get_wtime() - todata;if (id == 0)printf("Time spent is %lf sec \n", todata);}
}
在Windows的Visual Studio运行时报错了:
这个出错的位置比较有意思。
把Visual Studio的x64选项改成x86,运行成功:
先看看[Visual Studio] — Differences between x86, x64 and AnyCPU,关于Visual Studio的x86和x64选项是怎么回事?
1.32位操作系统和64位操作系统之间的区别:
(1) 32位CPU: 地址指针长度32位,可访问2^32个离散地址,这使得程序最多可以在内存中开出4GB的数据结构。
(2) 64位CPU: 地址指针长度64位,可以访问2^64个离散地址,这使得程序最多能在内存中开出16EB的数据结构
(3) 在物理内存的限制之外,64位CPU上的进程可以处理比32位CPU更大的数据集。
我这台电脑是64位操作系统。
试试把程序中的Openmp指令给注释掉,然后重新选择x64选项build然后运行:
#include <stdio.h>
#include <math.h>
#include <omp.h>#define ITER 100000000void main()
{int i;double A[ITER];for (i = 0; i < ITER; i++)A[i] = 2.0 * i;// ,#pragma omp parallel// {// int i;int id = omp_get_thread_num();double todata = omp_get_wtime();// #pragma omp for schedule(static)for (i = 1; i < ITER; i++)A[i] = A[i] * sqrt(i) / pow(sin(i), tan(i));todata = omp_get_wtime() - todata;if (id == 0)printf("Time spent is %lf sec \n", todata);// }
}
运行成功。
看来这和OpenMP的机制有关了。
恢复之前的OpenMP指令,把数组大小降低到100000:
#include <stdio.h>
#include <math.h>
#include <omp.h>#define ITER 100000void main()
{int i;double A[ITER];for (i = 0; i < ITER; i++)A[i] = 2.0 * i;#pragma omp parallel{int i;int id = omp_get_thread_num();double todata = omp_get_wtime();#pragma omp for schedule(static)for (i = 1; i < ITER; i++)A[i] = A[i] * sqrt(i) / pow(sin(i), tan(i));todata = omp_get_wtime() - todata;if (id == 0)printf("Time spent is %lf sec \n", todata);}
}
这样就运行成功了
具体原因还需要进一步查阅资料