【发布时间】:2018-10-25 09:59:36
【问题描述】:
以下代码是按顺序编写的。我想通过将 while 循环替换为 for 循环来实现 OpenMP,但不知道如何执行此操作。我知道 OpenMP 语法但无法实现。
进行并行的原因是为了检查顺序和并行技术之间的性能。有什么帮助吗?
void block::mine_block(uint32_t difficulty) noexcept
{
string str(difficulty, '0');
auto start = system_clock::now();
while (_hash.substr(0, difficulty) != str)
{
++_nonce;
_hash = calculate_hash();
}
auto end = system_clock::now();
duration<double> diff = end - start;
cout << "Block mined: " << _hash << " in " << diff.count() << " seconds" << endl;
}
@Matthieu Brucher - 这会是解决方案吗?
#pragma omp parallel // start the parallel region
{
#pragma omp single // let the while loop execute by one thread and generate tasks
while (time < TotalTime){
#pragma omp task
{
// this code will be a task that may be executed immediately on a different core or deferred for later execution
}
} // end of while loop and single region
// at this point we also wait until all tasks that were created have finished
} // end of parallel region
通过实现上述代码
#pragma omp parallel
{
#pragma omp single
while (_hash.substr(0, difficulty) != str) {
#pragma omp task
{
++_nonce;
_hash = calculate_hash();
}
}
}
【问题讨论】:
-
我可以猜测
calculate_hash的作用以及_nonce的使用方式,但我宁愿根据事实给出答案。请至少包含一些关于此的信息。避免使用全局变量,而是制定无副作用的函数。使并行化更容易。 -
我可以提供整个代码吗?
-
怎么保证
block::mine_block不会扔?str的构造可能会抛出,因为它分配内存(如果存储的字符串不短)。 -
一般来说,如果每次迭代的效果都依赖于之前的迭代,那么这样的循环是不能并行化的。
-
整个代码如果很长,并不总是可取的。通常你应该使用minimal reproducible example。我们需要知道的最重要的事情是
calculate_hash是否有任何副作用并使用任何全局数据。同样,假设它确实访问了全局变量_nonce,在尝试并行化之前,您应该首先将其重构为将其作为参数。
标签: c++ multithreading c++11 parallel-processing openmp