C++ OpenMP的线性加速比
我有一个简单的代码测试分配了更多内核时的加速次数,但是我没有观察到线性加速C++ OpenMP的线性加速比,c++,openmp,C++,Openmp,我有一个简单的代码测试分配了更多内核时的加速次数,但是我没有观察到线性加速 int main() { using u64_t = unsigned long long; u64_t n = 1e9; u64_t* a = new u64_t[n]; #pragma omp parallel for for (u64_t i=0; i<n; ++i) { a[i] = i; } } 为什么没有线性加速 更新 系统环境如下 in
int main() {
using u64_t = unsigned long long;
u64_t n = 1e9;
u64_t* a = new u64_t[n];
#pragma omp parallel for
for (u64_t i=0; i<n; ++i) {
a[i] = i;
}
}
为什么没有线性加速
更新
系统环境如下
int main() {
using u64_t = unsigned long long;
u64_t n = 1e9;
u64_t a[7];
#pragma omp parallel for
for (u64_t i=0; i<n; ++i) {
a[i%7] = i; // a is an array, I know there might be data race here
}
cout << a[0] << "," << a[6];
}
另外,htop
给了我4个线程,我怀疑如果启用了超线程,可能只有2个物理内核
我使用gnug++-7
编译的time./a.out
测量速度
后续行动
现在我稍微修改了代码,如下所示
int main() {
using u64_t = unsigned long long;
u64_t n = 1e9;
u64_t a[7];
#pragma omp parallel for
for (u64_t i=0; i<n; ++i) {
a[i%7] = i; // a is an array, I know there might be data race here
}
cout << a[0] << "," << a[6];
}
intmain(){
使用u64_t=无符号长;
u64_t n=1e9;
u64_t a[7];
#pragma-omp并行
对于(u64_t i=0;i此代码主要受内存带宽的限制,因为每个操作只写入一个值。通常,内存带宽小于所有内核并行使用的带宽
对内存饱和进行计算与规格有点不符。
您的系统可能有一个,在该配置中,它应该有25.6 GB/s的内存带宽。您只需要写入3.4 GB/s,对于写入,您通常使用两倍的速度,因为每次写入首先需要从内存读取缓存线。因此,在6.8 GB/s和理论带宽之间仍然有很大的间隔,但这并不是闻所未闻的f、 由于我没有完全相同的硬件,所以无法复制。要进行更详细的分析,必须深入研究生成的指令和硬件性能计数器
还有一些评论:
- 我听说苹果有时会把
gcc
和clang
混在一起,这可能会产生误导
- 您应该在循环之后使用
a
,以防止编译器优化它
- 您的时间测量包括应用非并行设置和<代码> new…< /代码>,因此您受到严重影响。只考虑并行的部分,使用<代码> OMPPGETYGWTIME()< <代码> >
-
综上所述,您的处理器只有两个内核(四个硬件线程),无论如何,您不应该期望超过两个线程的加速。此代码主要受内存带宽的限制,因为您每个操作写入一个值。通常,内存带宽小于所有内核并行使用的带宽
对内存饱和进行计算与规格有点不符。
您的系统可能有一个,在该配置中,它应该有25.6 GB/s的内存带宽。您只需要写入3.4 GB/s,对于写入,您通常使用两倍的速度,因为每次写入首先需要从内存读取缓存线。因此,在6.8 GB/s和理论带宽之间仍然有很大的间隔,但这并不是闻所未闻的f、 由于我没有完全相同的硬件,所以无法复制。要进行更详细的分析,必须深入研究生成的指令和硬件性能计数器
还有一些评论:
- 我听说苹果有时会把
gcc
和clang
混在一起,这可能会产生误导
- 您应该在循环之后使用
a
,以防止编译器优化它
- 您的时间测量包括应用非并行设置和<代码> new…< /代码>,因此您受到严重影响。只考虑并行的部分,使用<代码> OMPPGETYGWTIME()< <代码> >
-
综上所述,您的处理器只有两个内核(四个硬件线程),而且你不应该期望超过两个线程的加速。你有多少个内核?真正的内核。不是线程。这表明你有2个内核和4个线程。@更清楚,这是一个mac pro,htop
告诉我有4个,还有sysctl-n hw.ncpu
给了我4个,是吗?不知道。我没有mac,所以我不知道是什么htop
或sysctl
返回。请提供有关您的系统的信息:CPU型号和内存配置。编译器版本是什么。还请描述您如何测量时间。@Zulan已更新。您有多少内核?实际内核。不是线程。这表示您有2个内核和4个线程。@更清楚,这是mac pro,并且htop
告诉我有4个,也sysctl-nhw.ncpu
给了我4个,是吗?不知道。我没有mac电脑,所以我不知道htop
或sysctl
返回什么。请提供有关您的系统的信息:CPU型号和内存配置。编译器版本是什么。还要描述一下您是如何测量时间的。@Zul更新的。+1极好且专业的答案。几个快速问题:1)我自己安装了这个gnugcc
编译器,所以保证它不是macclang
。2)你说的阻止编译器优化它是什么意思后续,并行版本比串行版本慢,你能给我一个提示吗?请避免后续,因为后续可能是他们自己的问题,而原始问题已经得到了回答。+1很棒的专业答案。几个快速问题:1)我自己安装了这个gnugcc
编译器,所以保证它不是macclangg
.2)你说的阻止编译器优化它是什么意思?优化什么?3)是的,我计时的方式会计入new
,但是这个new
的操作成本可以忽略不计。我用后续的方法更新了原来的问题,并行版本比串行版本慢,可以吗给我一个提示为什么?请避免跟进,因为这些问题可能是他们自己的问题,并且原始问题已经得到了回答。