我正在尝试编写一些CUDA代码来计算最长的公共子序列。我无法弄清楚如何使线程休眠,直到满足计算它的单元格的依赖关系:
即
// Ignore the spurious maths here, very messy data structures. Planning ahead to strings that are bigger then GPU blocks. i & j are correct though.
int real_i = blockDim.x * blockIdx.x + threadIdx.x;
int real_j = blockDim.y * (max_offset - blockIdx.x) + threadIdx.y;
char i_char = seq1[real_i];
char j_char = seq2[real_j];
// For i & j = 1 to length
if((real_i > 0 && real_j > 0) && (real_i < sequence_length && real_j < sequence_length) {
printf("i: %d, j: %d\n", real_i, real_j);
printf("I need to wait for dependancy at i: %d j: %d and i: %d j: %d\n", real_i, (real_j - 1), real_i - 1, real_j);
printf("Is this true? %d\n", (depend[sequence_length * real_i + (real_j - 1)] && depend[sequence_length * (real_i - 1) + real_j]));
//WAIT FOR DEPENDENCY TO BE SATISFIED
//THIS IS WHERE I NEED THE CODE TO HANG
while( (depend[sequence_length * real_i + (real_j - 1)] == false) && (depend[sequence_length * (real_i - 1) + real_j] == false) ) {
}
if (i_char == j_char)
c[sequence_length * real_i + real_j] = (c[sequence_length * (real_i - 1) + (real_j - 1)]) + 1;
else
c[sequence_length * real_i + real_j] = max(c[sequence_length * real_i + (real_j - 1)], c[sequence_length * (real_i - 1) + real_j]);
// SETTING THESE TO TRUE SHOULD ALLOW OTHER THREADS TO BREAK PAST THE WHILE BLOCK
depend[sequence_length * real_i + (real_j - 1)] = true;
depend[sequence_length * (real_i - 1) + real_j] = true;
}
基本上,线程应该挂在while循环上,直到其依赖关系,在进入计算代码之前被其他线程满足。
我知道'first'线程在打印时满足其依赖性
real i 1, real j 1
I need to wait for dependancy at i: 1 j: 0 and i: 0 j: 1
Is this true? 1
一旦完成计算,将依赖矩阵中的一些单元格设置为true,允许另外2个线程通过while循环,内核从那里移动。
但是,如果我取消注释while循环,整个系统会挂起约10秒钟,然后我会
the launch timed out and was terminated
有什么建议吗?
答案 0 :(得分:1)
睡觉是个坏主意,最好等待条件变量或互斥量。
在GPU上,每个条件声明都非常昂贵。所以,如果可以的话,尝试并行化所有代码。要确保代码在所有线程中完成,您可以使用__syncthreads()
如果您仍想使用最简单的解决方案添加互斥锁,但这通常是个坏主意