gpt4 book ai didi

c++ - VS 自动并行化

转载 作者:太空宇宙 更新时间:2023-11-04 12:53:02 26 4
gpt4 key购买 nike

我试图了解自动并行化如何加速我正在编写的程序的执行。我创建了一个更简单的示例:

#include <iostream>
#include <vector>
#include <chrono>

using namespace std;
using namespace std::chrono;

class matrix
{
public:
matrix(int size, double value)
{
A.resize(size, vector<double>(size, value));
B.resize(size, vector<double>(size, value));
};
void prodScal(double valore)
{
for (int m = 0; m < A.size(); m++)
for (int n = 0; n < A.size(); n++)
{
B[m][n] = A[m][n] * valore;
};
};
double elemento(int riga, int column) { return B[riga][column]; }

protected:
vector<vector<double>> A, B;
};


void main()
{
matrix* M;
M = new matrix(1000, 174.9);
high_resolution_clock::time_point t1 = high_resolution_clock::now();

#pragma loop(hint_parallel(4))
for (int i = 0; i < 1000; i++)
M->prodScal(567.3);

high_resolution_clock::time_point t2 = high_resolution_clock::now();
auto duration = duration_cast<milliseconds>(t2 - t1).count();
cout << "execution time [ms]: " << duration << endl;
}
当我尝试使用 cl main.cpp /O2 /Qpar /Qpar-report:2 编译此代码时,我收到以下消息:

c:\users\utente\documents\visual studio 2017\projects\parallel\parallel\main.cpp(39) : info C5012: ciclo non parallelizzato a causa del motivo '500'

c:\users\utente\documents\visual studio 2017\projects\parallel\parallel\main.cpp(39) : info C5012: ciclo non parallelizzato a causa del motivo '500'

c:\users\utente\documents\visual studio 2017\projects\parallel\parallel\main.cpp(38) : info C5012: ciclo non parallelizzato a causa del motivo '1000'


你能帮我用正确的方法来并行化这个循环吗?
谢谢。

最佳答案

自动并行化的努力(或信念?)是一把双刃剑:

机器只能在一定程度上“猜测”一个意图(并且可以放弃,只要这种意图对于一组预先连接的转换策略不明确),所以不要指望大规模的任何聪明的技巧可能的不同方法。营销人员会鼓起勇气吹响所有的口哨来推销自动“思考”的产品,但现实却不同。即使是最优秀的人也承认,最好的性能来自指令级分析,有时他们甚至避免使用超标量流水线处理器编织技巧,以便获得最后几纳秒,在最后一级的并行代码性能中损失CPU uop 指令流。所以,最好不要指望仅仅通过使用 #pragma 就能获得这样的专业知识。代码部分相信,“机器”会发明一条最聪明的方法。

所以,测试它(总是彻底):

尝试“并行化”最外层 for(){...}不是最好的开始。无论是性能方面还是资源方面。让我们从另一个方面来解决这个问题,即计算本身:

#include <iostream>              // https://stackoverflow.com/questions/48033769/auto-parallelization-with-vs
#include <vector>
#include <chrono> // g++ FLAGS.ADD: -std=c++11
#include <omp.h> // g++ FLAGS.ADD: -fopenmp -lm
#define OMP_NUM_OF_THREADS 4

using namespace std;
using namespace std::chrono;

class matrix {
public:
matrix( int size, double value ) {
A.resize( size, vector<double>( size, value ) );
B.resize( size, vector<double>( size, value ) );
}
void prodScal( double aScalarVALORE ) {
// #pragma loop( hint_parallel(4) ) // matrix_(hint_parallel(4)).cpp:18:0: warning: ignoring #pragma loop [-Wunknown-pragmas]
#pragma omp parallel num_threads( OMP_NUM_OF_THREADS ) // _____ YET, AGNOSTIC TO ANY BETTER CACHE-LINE RE-USE POLICY
for ( unsigned int m = 0; m < A.size(); m++ )
for ( unsigned int n = 0; n < A.size(); n++ )
B[m][n] = A[m][n] * aScalarVALORE;
}
double elemento( int riga, int column ) { return B[riga][column]; }

protected:
vector<vector<double>> A, B;
};

int main() { // matrix_(hint_parallel(4)).cpp:31:11: error: ‘::main’ must return ‘int’

matrix* M;
M = new matrix( 1000, 174.9 );
high_resolution_clock::time_point t1 = high_resolution_clock::now();
// *******************
// DEFINITELY NOT HERE
// *******************
// #pragma loop(hint_parallel(4)) // JUST A TEST EXECUTION, NOT ANY PARALLELISATION BENEFIT FOR A PROCESS-PER-SE PERFORMANCE
for ( int i = 0; i < 1000; i++ )
M->prodScal( 567.3 );

high_resolution_clock::time_point t2 = high_resolution_clock::now();
auto duration = duration_cast<milliseconds>( t2 - t1 ).count();
cout << "execution time [ms]: " << duration << endl;
/*
* execution time [ms]: 21601
------------------
(program exited with code: 0)
* */
return 0;
}

一旦有了工作代码, 性能调整,以获得最大,是下一个障碍 .

更好地通过 for(){...}可以显着提高所有 MEM 提取的成本总和(为每个非缓存引用支付 ~ +100 [ns])v/s 缓存重用(为任何缓存重用支付 ~ +1.5 [ns])。

它取决于矩阵的全局大小、L3、L2 和 L1 高速缓存大小以及高速缓存行长度/关联性,更不用说如果代码要在虚拟机上运行的额外性能偏差设备。
Non-Uniform-Memory-Architecture topology with static sizes and hardware ID#-s
可以使用 lstopo 描述静态大小和近似的 NUMA 拓扑。 ( lscpu 在没有智能 hwloc 服务的情况下)。

在这里,您可以读取缓存容量,它可以保存矩阵单元,以实现智能重用的任何潜在加速(遵循 for(){...} 索引的缓存行跨步)。

调整 for() 可以获得最佳性能。 -循环步进,最好接近可用的 CPU 硬件 ILP 级别(使用 CPU 指令级并行可能的另一个并行度,允许共同执行的微指令链(引用 Intel CPU 关于这些细节的出版物)和最佳在目标平台上进行了测试(如果没有 objective-c PU 架构上的性能基准测试,交叉编译将无法进行此类优化,最好在目标平台上进行体内测试)。

此处的详细信息远远超出了此媒体格式的有限范围,在 StackOverflow 上,但如果对性能调整感兴趣,您肯定会发现来源和您自己的实验实践经验将指导您进一步的步骤。为了以某种方式感知权力,'已经做了一个大型矩阵线性代数项目来完成一些 [TB]矩阵处理从 ~ 126 小时减少到几分钟(不包括加载阶段,将矩阵数据放入 RAM ),通过非常仔细的并行代码设计,因此确实值得“正确”进行设计。

为了获得更高的性能,还必须避免 O/S 驱逐昂贵的预取数据,因此需要更多的努力来获得最终性能,而不仅仅是依靠自动化的“自动并行化”玩具。

结语 :
如果仍然存在疑问,如果这确实可能,那么如果“自动并行化”玩具会做得更好或至少与这些专家 Nerd 极客?他们不会,如果他们确实可以的话。

关于c++ - VS 自动并行化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48033769/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com