我有一组循环运行的操作。
for(int i = 0; i < row; i++)
{
sum += arr1[0] - arr2[0]
sum += arr1[0] - arr2[0]
sum += arr1[0] - arr2[0]
sum += arr1[0] - arr2[0]
arr1 += offset1;
arr2 += offset2;
}
现在我正在尝试像这样对象进行矢量化
for(int i = 0; i < row; i++)
{
convert_int4(vload4(0, arr1) - vload4(0, arr2));
arr1 += offset1;
arr2 += offset2;
}
但是如何在不使用循环的情况下在标量sum
中累积结果向量?
我正在使用OpenCL 2.0。
答案 0 :(得分:1)
该操作被称为&#34;减少&#34;似乎有一些信息here。
在OpenCL中,似乎实现了特殊功能,其中一个work_group_reduce()
可能会对您有所帮助:link。
包含一些代码的演示文稿:link。
答案 1 :(得分:1)
对于float2,float4等类似,最简单的版本可能是点积。 (从int转换为float可能很昂贵)
function getXMLValue(strXMLfile, XMLelement, infoID, XMLattrib)
'Declare local variables
Dim objXML, return_value
return_value = null
'Instantiate the XMLDOM Object that will hold the XML file.
set objXML = Server.CreateObject("Microsoft.XMLDOM")
'Turn off asyncronous file loading.
objXML.async = false
objXML.LoadXml(strXMLFile)
objXML.setProperty "SelectionLanguage", "XPath"
if XMLelement = "date" then
set return_value = objXML.selectSingleNode("date/@" & XMLattrib)
elseif XMLelement = "id" then
set return_value = objXML.selectSingleNode("subset/information[@id='" & infoID & "']/" & XMLattrib)
elseif XMLelement = "page_title" then
set return_value = objXML.selectSingleNode("page_title")
elseif XMLelement = "date_stamp" then
set return_value = objXML.selectSingleNode("date" & XMLvalue)
elseif XMLelement = "timestamp" then
set return_value = objXML.selectSingleNode("subset/information/[@id='" & infoID & "']/timestamp/@" & XMLattrib)
end if
if not(isnull(return_value)) then
getXMLvalue = return_value.text
end if
set return_value = nothing
set objXML = nothing
end function
这等于
float4 v1=(float4 )(1,2,3,4);
float4 v2=(float4 )(5,6,7,8);
float sum=dot(v1-v2,(float4)(1,1,1,1));
如果有任何硬件支持,将它留给编译器的怜悯应该没问题。对于较大的矢量,特别是阵列,J.H.Bonarius的答案是要走的路。据我所知,只有CPU有这样的垂直和操作,GPU没有这个,但为了便于携带,dot product和work_group_reduce是实现可读性甚至性能的最简单方法。
Dot产品有额外的乘法因此总是不好。
答案 2 :(得分:1)
我找到了一个解决方案,这似乎是我能够解决问题的最接近的方式。
uint sum = 0;
uint16 S0, S1;
for(int i = 0; i < row; i++)
{
S0 += convert_uint16(abs(vload16(0, arr1) - vload16(0, arr2)));
S1 += convert_uint16(abs(vload16(1, arr1) - vload16(1, arr2)));
arr1 += offset1;
arr2 += offset2;
}
S0 = S0 + S1;
S0.s01234567 = S0.s01234567 + S0.s89abcdef;
S0.s0123 = S0.s0123 + S0.s4567;
S0.s01 = S0.s01 + S0.s23;
sum = S0.s0 + S0.s1;
OpenCL 2.0通过向量提供此功能,其中向量的元素可以连续替换为如上所示的加法运算。这可以支持最大为16的向量。较大的操作可以分成较小操作的因子。例如,为了在两个大小为32的向量之间添加差异的绝对值,我们可以执行以下操作:
<html>
<head>
<title>Title</title>
</head>
<body>
<p>Hello {greeting}!</p>
<table><tr>
<td>Details:</td>
<td>{details}</td>
</tr></table>
</body>
</html>