cl::vector 与 std::vector:不同的迭代器行为
编辑:按照 PlasmaHH 的建议添加了带有内存位置的调试输出。
我不明白 cl::vector<> 的不同行为在 OpenCL 的 C++ 绑定中。考虑以下代码:
标头 Top.hpp
:
class Top {
public:
void setBool(bool b);
bool getBool();
private:
bool status;
};
源 Top.cpp
:
#include "Top.hpp"
void Top::setBool(bool b) {
std::cout << (void*)this << " setBool("<< b<< ")\n";
status = b;
}
bool Top::getBool() {
std::cout << (void*)this << " getBool() returns " << status << std::endl;
return status;
}
使用上面的内容:
#define __NO_STD_VECTOR
#include <iostream>
#include "CL/cl.hpp"
#include "Top.hpp"
using namespace cl;
using namespace std;
cl::vector<Top> js;
int main() {
js.push_back(Top());
js[0].setBool(true);
cout << js[0].getBool() << endl;
for(cl::vector<Top>::iterator i = js.begin(); i != js.end(); ++i) {
(*i).setBool(false);
}
cout << js[0].getBool() << endl;
}
使用 __NO_STD_VECTOR
,std::vector 被覆盖。输出是
0x6021c0 setBool(1)
0x6021c0 getBool() returns 1
0x7fffae671d60 setBool(0)
0x6021c0 getBool() returns 1
所以迭代器返回的位置肯定是错误的。
然而,将上面的内容与 std::vector 一起使用(当然,并将命名空间更改为 std::vector )会给出预期的输出:
0x1be0010 setBool(1)
0x1be0010 getBool() returns 1
0x1be0010 setBool(0)
0x1be0010 getBool() returns 0
此迭代器的行为不同,但它应该替换std::vector 以避免兼容性问题。我错过了什么吗?
EDIT: Added debugging output with memory locations as suggested by PlasmaHH.
I don't understand the different behaviour of the cl::vector<> in the C++ bindings for OpenCL. Consider the following code:
Header Top.hpp
:
class Top {
public:
void setBool(bool b);
bool getBool();
private:
bool status;
};
Source Top.cpp
:
#include "Top.hpp"
void Top::setBool(bool b) {
std::cout << (void*)this << " setBool("<< b<< ")\n";
status = b;
}
bool Top::getBool() {
std::cout << (void*)this << " getBool() returns " << status << std::endl;
return status;
}
Use the above:
#define __NO_STD_VECTOR
#include <iostream>
#include "CL/cl.hpp"
#include "Top.hpp"
using namespace cl;
using namespace std;
cl::vector<Top> js;
int main() {
js.push_back(Top());
js[0].setBool(true);
cout << js[0].getBool() << endl;
for(cl::vector<Top>::iterator i = js.begin(); i != js.end(); ++i) {
(*i).setBool(false);
}
cout << js[0].getBool() << endl;
}
With __NO_STD_VECTOR
the std::vector is overridden. The output is
0x6021c0 setBool(1)
0x6021c0 getBool() returns 1
0x7fffae671d60 setBool(0)
0x6021c0 getBool() returns 1
So the location returned by the iterator is definitely wrong.
Using the above with the std::vector
(and changing the namespaces to std
of course) however gives the expected output:
0x1be0010 setBool(1)
0x1be0010 getBool() returns 1
0x1be0010 setBool(0)
0x1be0010 getBool() returns 0
This iterator is acting differently, but it's supposed to replace the std::vector to avoid compatibility issues. Am I missing something?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
不管怎样,我都不是 OpenCL 方面的专家,但我很感兴趣,所以我转到了 CUDA/OpenCL计算。我发现他们的 * 运算符返回一个副本而不是引用:
而(第一个,非常量)向量 [] 运算符返回一个引用:
尝试直接迭代向量(使用旧的“int i = 0, ... ") 并看看是否会产生不同的结果。如果是这样,您可能需要放入错误报告(首先检查),因为这对于 * 运算符来说是意外行为。
Not an expert at OpenCL by any stretch of the imagination, but I'm interested so I went over to CUDA/OpenCL Computing. I appears that their * operator returns a copy rather than a reference:
Whereas the (first, non-const) vector [] operator returns a reference:
Try iterating through the vector directly (using the old "int i = 0, ...") and see if that gives different results. If so, you might want to put in a bug report (check first) since this is unexpected behavior for the * operator.
从地址来看,我怀疑这是一个 64 位构建,并且 cl 向量的迭代器的
operator*
按值而不是按引用返回,不允许访问原始元素。作为实验,您可以尝试使用->
运算符代替i->setBool(false);
来查看是否正确实现。Judging from the addresses I suspect that this is a 64-bit build and that the cl vector's iterator's
operator*
is returning by value rather than by reference, not allowing access to the original element. As an experiment you could try using the->
operator insteadi->setBool(false);
to see if that's implemented sanely.