gpt4 book ai didi

c - 如何在 OpenMP 中使用归约 vector 变量?

转载 作者:行者123 更新时间:2023-11-30 19:15:24 26 4
gpt4 key购买 nike

我想在 openmp 中使用 reduction 指令,但它不起作用。编译器错误说:

"reduction: OpenMP 'parallel for' empty factor in directive" (Visual studio 2015 community)

"reduction:^ needed scalar variable"

这是我的代码(字节是unsigned char)

void RotXOR (const Byte *s, int n, Byte *t)
{
int i = 0, q;
q = n / 8; n %= 8;

#pragma omp parallel for private(i) reduction()
for (i = 0; i < 16; i++) {
t[(q + i) % 16] ^= (s[i] >> n);

if (n != 0) {
t[(q + i + 1) % 16] ^= (s[i] << (8 - n));
}
}
}

最佳答案

来自 C/C++ 的 OpenMP 4.0 标准 p171:

Arrays may not appear in a reduction clause.

因此,唯一的方法是创建一个初始化为 0 的本地每线程“tt”数组,在其之上进行计算并更新 ttt退出并行部分时以原子方式进行。

但不管怎样,由于你的循环次数只有 16,并行化开销将远远大于任何潜在的 yield ,所以从我的角度来看,这只是一个死胡同。

<小时/>

编辑:这就是我的想法:

void RotXOR( const Byte *s, int n, Byte *t ) {
int q = n / 8;
n %= 8;

#pragma omp parallel
{
int tt[] = { 0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0 };
#pragma omp for
for ( int i = 0; i < 16; i++ ) {
tt[( q + i ) % 16] ^= ( s[i] >> n );
if ( n != 0 ) {
tt[( q + i + 1 ) % 16] ^= ( s[i] << ( 8 - n ) );
}
}
#pragma omp critical
for ( int i = 0; i < 16; i++ ) {
t[i] ^= tt[i];
}
}
}

我说过我不期望有太大的性能改进(如果有的话),因为行程计数非常小,没有太多工作可以在线程之间分配来隐藏线程管理的开销以及顺序最终减少。

在编写此解决方案时,我想到了另一个解决方案,但我不知道这两个版本中哪一个性能最好...我怀疑第二个版本会比第一个版本更糟糕,因为同步开销很大并且虚假分享t ,但我不确定...

void RotXOR( const Byte *s, int n, Byte *t ) {
int q = n / 8;
n %= 8;

#pragma omp parallel for
{
for ( int i = 0; i < 16; i++ ) {
int idx = ( q + i ) % 16;
int val = s[i] >> n;
#pragma omp atomic
t[idx] ^= val;
if ( n != 0 ) {
idx = ( q + i + 1 ) % 16;
val = s[i] << ( 8 - n );
#pragma omp atomic
t[idx] ^= val;
}
}
}
}

最后,由于 n 的值在输入时已知,我想删除 if循环中的语句将是一个好主意,即使它意味着编写更多的代码。

关于c - 如何在 OpenMP 中使用归约 vector 变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32645298/

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