我有一个文本(大约136.000
个字符),我想在一张图片中写下来。我的文字存储在vector
中,这意味着我可以使用循环for
来更改像素的low bit
。
这是函数更改last bit
:
int changeLastChar(int value, int newEnd) {
// change last decimal of an integer
if (newEnd > 9) return 1;
value /= 10;
value *= 10;
value += newEnd;
return value;
}
这张正在写一张图片:
void writeTextToImage3(Mat& image, std::vector<char> message, int count) {
// write text to pixels by changing the last decimal in every RGB value
int ascii;
int row;
int col;
#pragma omp parallel
{
#pragma omp for
for (int i = 0; i < message.size(); i++)
{
row = count/ image.cols;
col = count % image.cols;
ascii = message[i];
count++;
image.at<Vec3b>(row, col)[0] = changeLastChar(image.at<Vec3b>(row, col)[0], ascii % 10); // blue
ascii /= 10;
image.at<Vec3b>(row, col)[1] = changeLastChar(image.at<Vec3b>(row, col)[1], ascii % 10); // green
ascii /= 10;
image.at<Vec3b>(row, col)[2] = changeLastChar(image.at<Vec3b>(row, col)[2], ascii % 10); // red
}
}
}
我可以提供一些结果,如果我使用函数without OpenMP
,则需要:0.29..
。
With OpenMP
使用#pragma omp for
:0.26..
With OpenMP
使用#pragma omp parallel for
:0.17..
我知道for
和parallel for
之间的区别,如果我只使用for
,我只有一个主线程,而不是一个群组。
但至于我的问题:每row
我需要一个确切的col
和ascii
个数字。我看到花时间的差异,我真的很想看0.17..
。但是..如果我清楚地理解,当我使用parallel for
时:它创建了几个线程,迭代的每个部分都适用于几个线程的每个线程。好的。
但是我无法理解,为什么它只适用于the first iteration
而其他人不能继续改变位?
我的想法是:当某个部分(不是第一个,某些......)正常工作时,它会计算变量cout++
,计算row and col
。当然,它从0
开始计算,但我需要从THE FIRST THREAD
计算0
,而不是某些部分。
这就是为什么如果我不使用parallel
,它会按正确的顺序排列,因为它有一个主线程。
parallel for
吗?
答案 0 :(得分:1)
由于count
在所有线程之间共享,因此在每个循环中都会写入竞争条件。您还可以在局部变量上获得竞争条件,这些条件应该在循环内而不是在循环之外声明(这样每个线程都有自己的副本)。
i
时,您已经count
递增,所以您可以使用它。请勿修改count
,将row
和col
计算更改为count
使用i
:
int row = (count + i) / image.cols;
int col = (count + i) % image.cols;
int ascii = message[i];
您也可以只调用image.at<Vec3b>(row, col)
一次,将结果存储在变量中,然后使用:
auto &v = image.at<Vec3b>(row, col);
v[0] = changeLastChar(v[0], ascii % 10);
// etc.