<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Soul Of Free Loop &#187; GPU</title>
	<atom:link href="https://zohead.com/archives/tag/gpu/feed/" rel="self" type="application/rss+xml" />
	<link>https://zohead.com</link>
	<description>Uranus Zhou&#039;s Blog</description>
	<lastBuildDate>Sat, 19 Jul 2025 15:42:46 +0000</lastBuildDate>
	<language>zh-CN</language>
		<sy:updatePeriod>hourly</sy:updatePeriod>
		<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.8</generator>
	<item>
		<title>Linux C++程序使用Intel OpenCL的问题</title>
		<link>https://zohead.com/archives/cplus-intel-opencl/</link>
		<comments>https://zohead.com/archives/cplus-intel-opencl/#comments</comments>
		<pubDate>Sat, 26 May 2018 15:25:46 +0000</pubDate>
		<dc:creator><![CDATA[Uranus Zhou]]></dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[OpenCL]]></category>
		<category><![CDATA[CentOS]]></category>
		<category><![CDATA[GPU]]></category>
		<category><![CDATA[Intel]]></category>

		<guid isPermaLink="false">https://zohead.com/?p=1531</guid>
		<description><![CDATA[Intel OpenCL 问题 最近想在 Linux 环境下使用 Intel 核显测试我们的某个程序，该程序是用 C++ 写的，主要调用 OpenCL 库使用 GPU 进行运算。之前我用 AMD 和 NVIDIA 的显卡都测试过没有问题，还以为会比较顺利，结果在程序刚开始调用 clGetPlatformIDs 检测 OpenCL platform 的时候就直接报错退出了。 我的测试环境使用的是 Intel i3-6100 CPU，该处理器自带 Intel HD Graphics 530 核显，操作系统则是 CentOS 6.9 64 位（比较老，为了和使用环境一致），安装的也是 Intel 官 [&#8230;]]]></description>
				<content:encoded><![CDATA[<h2 id="intel-opencl-bug">Intel OpenCL 问题</h2>
<p>最近想在 Linux 环境下使用 Intel 核显测试我们的某个程序，该程序是用 C++ 写的，主要调用 OpenCL 库使用 GPU 进行运算。之前我用 AMD 和 NVIDIA 的显卡都测试过没有问题，还以为会比较顺利，结果在程序刚开始调用 <code>clGetPlatformIDs</code> 检测 OpenCL platform 的时候就直接报错退出了。</p>
<p>我的测试环境使用的是 Intel i3-6100 CPU，该处理器自带 Intel HD Graphics 530 核显，操作系统则是 CentOS 6.9 64 位（比较老，为了和使用环境一致），安装的也是 Intel 官方网站上提供的 Intel OpenCL 2.0 Driver（SRB 5.0 版本），具体可以参考 Intel 官网的 <a href="https://software.intel.com/en-us/articles/opencl-drivers" target="_blank">OpenCL™ Drivers and Runtimes for Intel® Architecture</a> 介绍。</p>
<p>值得一提的是 Intel OpenCL Driver 安装完成之后，运行 <code>clinfo</code> 命令是可以正常识别到核显的，而且我使用另外一个通过 OpenCL 进行计算的 C 程序来测试又是完全没问题的。</p>
<h2 id="debug-opencl">调试分析</h2>
<p>初步考虑可能 Intel OpenCL 在此系统和 C++ 程序存在兼容性问题，为此我先写了一个最简单的 C++ 程序来检测 OpenCL platform：</p>
<pre class="brush: cpp; highlight: [9]; title: cl.cpp; notranslate">
#include &lt;iostream&gt;
#include &lt;string&gt;
#include &lt;CL/cl.h&gt;

void init_cl()
{
	cl_uint plats = 0;
	std::cout &lt;&lt; &quot;Begin get OpenCL platform.&quot; &lt;&lt; std::endl;
	clGetPlatformIDs(0, NULL, &amp;plats);
	std::cout &lt;&lt; &quot;OpenCL platforms: &quot; &lt;&lt; plats &lt;&lt; std::endl;
}

int main(int argc, char **argv)
{
	std::string str = &quot;cl&quot;;
	init_cl();
	return 0;
}
</pre>
<p>使用 <code>g++</code> 编译该测试程序，编译时启用优化：</p>
<pre class="brush: bash; title: ; notranslate">
[root@localhost ~]# g++ -O2 -o cl cl.cpp -lOpenCL -lstdc++
</pre>
<p>测试程序使用 AMD 和 NVIDIA 显卡的 OpenCL 库都可以正常检测到 platform，使用 Intel 核显则会遇到下面的错误：</p>
<pre class="brush: bash; title: ; notranslate">
[root@localhost tmp]# ./cl
Begin get OpenCL platform.
*** glibc detected *** ./cl: free(): invalid pointer: 0x0000003de60f32c0 ***
======= Backtrace: =========
/lib64/libc.so.6[0x328cc75716]
/usr/lib64/libstdc++.so.6(_ZNSs6assignERKSs+0x85)[0x3de5e9d565]
/opt/intel/opencl/libigdmcl.so(+0x2040ba)[0x7f75360a00ba]
/opt/intel/opencl/libigdmcl.so(+0x1e6cc2)[0x7f7536082cc2]
/lib64/ld-linux-x86-64.so.2[0x328c40e4ef]
/lib64/ld-linux-x86-64.so.2[0x328c412bf2]
/lib64/ld-linux-x86-64.so.2[0x328c40e106]
/lib64/ld-linux-x86-64.so.2[0x328c41245a]
/lib64/libdl.so.2[0x328c800f66]
/lib64/ld-linux-x86-64.so.2[0x328c40e106]
/lib64/libdl.so.2[0x328c80129c]
/lib64/libdl.so.2(dlopen+0x31)[0x328c800ee1]
/opt/intel/opencl/libigdrcl.so(+0x124bd3)[0x7f7538082bd3]
/opt/intel/opencl/libigdrcl.so(+0xf4890)[0x7f7538052890]
/opt/intel/opencl/libigdrcl.so(+0xf4e26)[0x7f7538052e26]
/opt/intel/opencl/libigdrcl.so(+0xe8982)[0x7f7538046982]
/opt/intel/opencl/libigdrcl.so(+0xd0f3c)[0x7f753802ef3c]
/opt/intel/opencl/libigdrcl.so(clIcdGetPlatformIDsKHR+0x2b)[0x7f753801a0ab]
/opt/intel/opencl/libIntelOpenCL.so(+0x234e4)[0x7f75388c34e4]
/opt/intel/opencl/libIntelOpenCL.so(+0x3f20)[0x7f75388a3f20]
/usr/lib64/libOpenCL.so.1(+0x298b)[0x7f7538f0b98b]
/usr/lib64/libOpenCL.so.1(+0x4907)[0x7f7538f0d907]
/lib64/libpthread.so.0(pthread_once+0x53)[0x7f7538adfe03]
/usr/lib64/libOpenCL.so.1(clGetPlatformIDs+0x11)[0x7f7538f0bf21]
./cl[0x400c6e]
./cl[0x400d31]
/lib64/libc.so.6(__libc_start_main+0xfd)[0x328cc1ec9d]
./cl[0x400b09]
======= Memory map: ========
00400000-00402000 r-xp 00000000 00:11 10291                              /tmp/cl
00601000-00602000 rw-p 00001000 00:11 10291                              /tmp/cl
0179d000-017be000 rw-p 00000000 00:00 0                                  [heap]
328c400000-328c420000 r-xp 00000000 fd:00 7124                           /lib64/ld-2.12.so
328c61f000-328c620000 r--p 0001f000 fd:00 7124                           /lib64/ld-2.12.so
328c620000-328c621000 rw-p 00020000 fd:00 7124                           /lib64/ld-2.12.so
328c621000-328c622000 rw-p 00000000 00:00 0
328c800000-328c802000 r-xp 00000000 fd:00 7116                           /lib64/libdl-2.12.so
328c802000-328ca02000 ---p 00002000 fd:00 7116                           /lib64/libdl-2.12.so
328ca02000-328ca03000 r--p 00002000 fd:00 7116                           /lib64/libdl-2.12.so
328ca03000-328ca04000 rw-p 00003000 fd:00 7116                           /lib64/libdl-2.12.so
328cc00000-328cd87000 r-xp 00000000 fd:00 6933                           /lib64/libc-2.12.so
328cd87000-328cf87000 ---p 00187000 fd:00 6933                           /lib64/libc-2.12.so
328cf87000-328cf8b000 r--p 00187000 fd:00 6933                           /lib64/libc-2.12.so
328cf8b000-328cf8c000 rw-p 0018b000 fd:00 6933                           /lib64/libc-2.12.so
328cf8c000-328cf91000 rw-p 00000000 00:00 0
328d400000-328d483000 r-xp 00000000 fd:00 6818                           /lib64/libm-2.12.so
328d483000-328d682000 ---p 00083000 fd:00 6818                           /lib64/libm-2.12.so
328d682000-328d683000 r--p 00082000 fd:00 6818                           /lib64/libm-2.12.so
328d683000-328d684000 rw-p 00083000 fd:00 6818                           /lib64/libm-2.12.so
328d800000-328d807000 r-xp 00000000 fd:00 7077                           /lib64/librt-2.12.so
328d807000-328da06000 ---p 00007000 fd:00 7077                           /lib64/librt-2.12.so
328da06000-328da07000 r--p 00006000 fd:00 7077                           /lib64/librt-2.12.so
328da07000-328da08000 rw-p 00007000 fd:00 7077                           /lib64/librt-2.12.so
3de5e00000-3de5ee8000 r-xp 00000000 00:11 9623                           /usr/lib64/libstdc++.so.6.0.13
3de5ee8000-3de60e8000 ---p 000e8000 00:11 9623                           /usr/lib64/libstdc++.so.6.0.13
3de60e8000-3de60ef000 r--p 000e8000 00:11 9623                           /usr/lib64/libstdc++.so.6.0.13
3de60ef000-3de60f1000 rw-p 000ef000 00:11 9623                           /usr/lib64/libstdc++.so.6.0.13
3de60f1000-3de6106000 rw-p 00000000 00:00 0
7f7535c86000-7f7535c9b000 r-xp 00000000 fd:00 7143                       /lib64/libz.so.1.2.3
7f7535c9b000-7f7535e9a000 ---p 00015000 fd:00 7143                       /lib64/libz.so.1.2.3
7f7535e9a000-7f7535e9b000 r--p 00014000 fd:00 7143                       /lib64/libz.so.1.2.3
7f7535e9b000-7f7535e9c000 rw-p 00015000 fd:00 7143                       /lib64/libz.so.1.2.3
7f7535e9c000-7f7536b3a000 r-xp 00000000 07:05 10                         /opt/intel/opencl/libigdmcl.so
7f7536b3a000-7f7536d3a000 ---p 00c9e000 07:05 10                         /opt/intel/opencl/libigdmcl.so
7f7536d3a000-7f7536d91000 r--p 00c9e000 07:05 10                         /opt/intel/opencl/libigdmcl.so
7f7536d91000-7f7536d93000 rw-p 00cf5000 07:05 10                         /opt/intel/opencl/libigdmcl.so
7f7536d93000-7f7536d9f000 rw-p 00000000 00:00 0
7f7536d9f000-7f7536da7000 r-xp 00000000 fd:00 13144                      /usr/lib64/libpciaccess.so.0.11.1
7f7536da7000-7f7536fa7000 ---p 00008000 fd:00 13144                      /usr/lib64/libpciaccess.so.0.11.1
7f7536fa7000-7f7536fa8000 rw-p 00008000 fd:00 13144                      /usr/lib64/libpciaccess.so.0.11.1
7f7536fa8000-7f7537351000 r-xp 00000000 07:05 12                         /opt/intel/opencl/libmd.so
7f7537351000-7f7537550000 ---p 003a9000 07:05 12                         /opt/intel/opencl/libmd.so
7f7537550000-7f7537554000 r--p 003a8000 07:05 12                         /opt/intel/opencl/libmd.so
7f7537554000-7f7537556000 rw-p 003ac000 07:05 12                         /opt/intel/opencl/libmd.so
7f7537556000-7f753755d000 rw-p 00000000 00:00 0
7f753755d000-7f753755e000 ---p 00000000 00:00 0
7f753755e000-7f7537f5e000 rw-p 00000000 00:00 0
7f7537f5e000-7f7538152000 r-xp 00000000 07:05 11                         /opt/intel/opencl/libigdrcl.so
7f7538152000-7f7538351000 ---p 001f4000 07:05 11                         /opt/intel/opencl/libigdrcl.so
7f7538351000-7f7538357000 r--p 001f3000 07:05 11                         /opt/intel/opencl/libigdrcl.so
7f7538357000-7f7538894000 rw-p 001f9000 07:05 11                         /opt/intel/opencl/libigdrcl.so
7f7538894000-7f75388a0000 rw-p 00000000 00:00 0
7f75388a0000-7f75388cb000 r-xp 00000000 07:05 2                          /opt/intel/opencl/libIntelOpenCL.so
7f75388cb000-7f7538acb000 ---p 0002b000 07:05 2                          /opt/intel/opencl/libIntelOpenCL.so
7f7538acb000-7f7538acc000 r--p 0002b000 07:05 2                          /opt/intel/opencl/libIntelOpenCL.so
7f7538acc000-7f7538acd000 rw-p 0002c000 07:05 2                          /opt/intel/opencl/libIntelOpenCL.so
7f7538acd000-7f7538ad3000 rw-p 00000000 00:00 0
7f7538ad3000-7f7538aea000 r-xp 00000000 fd:00 7139                       /lib64/libpthread-2.12.so
7f7538aea000-7f7538cea000 ---p 00017000 fd:00 7139                       /lib64/libpthread-2.12.so
7f7538cea000-7f7538ceb000 r--p 00017000 fd:00 7139                       /lib64/libpthread-2.12.so
7f7538ceb000-7f7538cec000 rw-p 00018000 fd:00 7139                       /lib64/libpthread-2.12.so
7f7538cec000-7f7538cf2000 rw-p 00000000 00:00 0
7f7538cf2000-7f7538d08000 r-xp 00000000 fd:00 7140                       /lib64/libgcc_s-4.4.7-20120601.so.1
7f7538d08000-7f7538f07000 ---p 00016000 fd:00 7140                       /lib64/libgcc_s-4.4.7-20120601.so.1
7f7538f07000-7f7538f08000 rw-p 00015000 fd:00 7140                       /lib64/libgcc_s-4.4.7-20120601.so.1
7f7538f08000-7f7538f09000 rw-p 00000000 00:00 0
7f7538f09000-7f7538f10000 r-xp 00000000 fd:00 12875                      /usr/lib64/libOpenCL.so.1
7f7538f10000-7f753910f000 ---p 00007000 fd:00 12875                      /usr/lib64/libOpenCL.so.1
7f753910f000-7f7539110000 rw-p 00006000 fd:00 12875                      /usr/lib64/libOpenCL.so.1
7f7539110000-7f7539111000 rw-p 00000000 00:00 0
7ffe17048000-7ffe17069000 rw-p 00000000 00:00 0                          [stack]
7ffe170de000-7ffe170e1000 r--p 00000000 00:00 0                          [vvar]
7ffe170e1000-7ffe170e3000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Aborted
</pre>
<p>从错误输出来看是 <code>clGetPlatformIDs</code> 调用过程中 Intel OpenCL Driver 内部就出现问题了，释放了无效的指针导致程序异常退出。</p>
<p>几番修改测试之后我发现两个现象：</p>
<ol>
<li>如果 <code>g++</code> 编译时不使用优化选项（<code>-O2</code> 参数去掉或者改为 <code>-O0</code>），则程序可以正常运行；</li>
<li>如果去掉第 15 行的 <code>std::string</code> 变量定义代码，即使保持优化选项开启并链接 libstdc++ 库，程序也可以正常运行。</li>
</ol>
<p>看起来只要 libstdc++ 库确实被使用了，优化过的 C++ 程序调用 Intel OpenCL 就会出现异常，而由于我们的程序需要开启编译器优化，因此要找到其它解决办法。</p>
<h2 id="fix-intel-opencl">解决方法</h2>
<h3 id="opt-off">局部关闭编译器优化</h3>
<p>我们可以在整个程序开启编译器优化的情况下，只关闭对调用 OpenCL 库那部分代码的优化。下面是两种局部关闭编译器优化的方法，通过这两种方法修改的测试程序编译之后都可以正常运行。</p>
<h4 id="pragma-opt">pragma 指令</h4>
<p>把测试程序的代码改成这样：</p>
<pre class="brush: cpp; title: ; notranslate">
#pragma GCC push_options
#pragma GCC optimize (&quot;O0&quot;)
void init_cl()
{
	...
}
#pragma GCC pop_options
</pre>
<p>使用 pragma 指令指定 <code>#pragma GCC push_options</code> 和 <code>#pragma GCC pop_options</code> 包起来的这部分代码的编译选项，好处是可以包含多个函数。</p>
<h4 id="attribute-opt">__attribute__ 属性</h4>
<p>我们也可以直接通过 GNU 编译器的 <code>__attribute__</code> 编译器属性指定某个函数的优化选项：</p>
<pre class="brush: cpp; title: ; notranslate">
void __attribute__((optimize(&quot;O0&quot;))) init_cl()
</pre>
<h3 id="update-libstdc++">升级 libstdc++ 库</h3>
<p>不过有点悲剧的是我们的 C++ 程序通过上面两种方法关闭 OpenCL 调用部分代码的编译器优化之后，运行之后仍然异常退出。另外我把程序挪到 CentOS 7.1 64 位系统上运行则没有任何问题，最终考虑要通过升级 libstdc++ 库（CentOS 6.9 上的是 4.4.7-18 版本）来解决此问题。</p>
<p>本来打算通过手工编译新版本 GCC 来生成新版本的 libstdc++ 库，不过还好搜索之后发现网上已经有现成的 CentOS 6 上的新版本 libstdc++ 了，具体可以参考 SAP 公司提供的 <a href="https://help.sap.com/viewer/d1469c16b1ed48bcb589c3a3f828cbc4/3.2/en-US/4236c03b3a1b42bdb7dd954f416e557d.html" target="_blank">compat-sap-c++ for RedHat 6.7+</a>。</p>
<p>按照 SAP 网站上的说明安装 <code>compat-sap-c++</code> 包，我们也可以直接替换系统链接：</p>
<pre class="brush: bash; title: ; notranslate">
[root@localhost ~]# curl -O ftp://ftp.pbone.net/mirror/ftp.scientificlinux.org/linux/scientific/6.7/x86_64/updates/fastbugs/compat-sap-c++-4.8.2-16.el6.x86_64.rpm
[root@localhost ~]# rpm -ivh compat-sap-c++-4.8.2-16.el6.x86_64.rpm
[root@localhost ~]# ln -sfn /opt/rh/SAP/lib64/compat-sap-c++.so /usr/lib64/libstdc++.so.6
</pre>
<p>替换 libstdc++ 为 4.8.2-16 版本之后再运行 OpenCL 测试程序就会发现即使开启编译器优化也没有问题了：</p>
<pre class="brush: bash; title: ; notranslate">
[root@localhost tmp]# ./cl
Begin get OpenCL platform.
OpenCL platforms: 1
</pre>
<p>看来 Intel 官网上介绍的 Intel OpenCL Driver 只验证了 CentOS 7.2、7.3 及 Ubuntu 16.04 系统下的兼容性还算靠谱的，如果要在老一点的 Linux 系统上使用 Intel OpenCL 还是需要尽量避免碰坑，最后祝大家玩的开心。</p>
]]></content:encoded>
			<wfw:commentRss>https://zohead.com/archives/cplus-intel-opencl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
