<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Hash_Key aus double-vector möglichst schnell: Ideen gesucht]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe eine Funktion die mir aus einem double-vector einen möglichst kollisionsfreien Schlüssel generiert. Das funktioniert auch einwandfrei - nur laut meinem Profiling wird da ziemlich viel Zeit verbraten (~5-8%).</p>
<p>Die Berechnung dieser schlüssel läuft innerhalb von for-schleifen, d.h sie kann unter umständen mehrere 10000-mal aufgerufen werden.</p>
<p>Was ich bisher verwendet habe war das folgende:</p>
<pre><code class="language-cpp">typedef unsigned int U_Int32;

template &lt;&gt;	U_Int32 
Cache&lt;double&gt;::Compute_Key(	const double* vec, 
							size_t size) const
{                    
	U_Int32 ret = 0;
	U_Int32 mix = Hash_Double(0.13);
	while(size--)
	{
		ret = (ret * 31) + mix + Hash_Double(*vec);
		vec++;
	} 
	return ret;
}

template &lt;class T&gt;	inline U_Int32 
Cache&lt;T&gt;::Hash_Double(double x)
{ 
	// 	U_Int64* p = reinterpret_cast&lt; U_Int64* &gt; (&amp;x); 
	// 	return *p ^ (*p &gt;&gt; 32); 

	U_Int32 p[2];
	memcpy( p, &amp;x, sizeof p );
	return p[0] ^ p[1];
}
</code></pre>
<p>Was dort passiert: Ich iteriere über jeden wert des vectors und ver-XODERe die oberen 32 Bit mit den unteren.</p>
<p>Also eine Iteration über alle Elemente ist ja schon mal zwingend....obs noch schneller geht?</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/194907/hash_key-aus-double-vector-möglichst-schnell-ideen-gesucht</link><generator>RSS for Node</generator><lastBuildDate>Tue, 29 Sep 2026 20:18:38 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/194907.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 11 Oct 2007 21:46:11 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to Hash_Key aus double-vector möglichst schnell: Ideen gesucht on Thu, 11 Oct 2007 21:46:11 GMT]]></title><description><![CDATA[<p>Hallo,</p>
<p>ich habe eine Funktion die mir aus einem double-vector einen möglichst kollisionsfreien Schlüssel generiert. Das funktioniert auch einwandfrei - nur laut meinem Profiling wird da ziemlich viel Zeit verbraten (~5-8%).</p>
<p>Die Berechnung dieser schlüssel läuft innerhalb von for-schleifen, d.h sie kann unter umständen mehrere 10000-mal aufgerufen werden.</p>
<p>Was ich bisher verwendet habe war das folgende:</p>
<pre><code class="language-cpp">typedef unsigned int U_Int32;

template &lt;&gt;	U_Int32 
Cache&lt;double&gt;::Compute_Key(	const double* vec, 
							size_t size) const
{                    
	U_Int32 ret = 0;
	U_Int32 mix = Hash_Double(0.13);
	while(size--)
	{
		ret = (ret * 31) + mix + Hash_Double(*vec);
		vec++;
	} 
	return ret;
}

template &lt;class T&gt;	inline U_Int32 
Cache&lt;T&gt;::Hash_Double(double x)
{ 
	// 	U_Int64* p = reinterpret_cast&lt; U_Int64* &gt; (&amp;x); 
	// 	return *p ^ (*p &gt;&gt; 32); 

	U_Int32 p[2];
	memcpy( p, &amp;x, sizeof p );
	return p[0] ^ p[1];
}
</code></pre>
<p>Was dort passiert: Ich iteriere über jeden wert des vectors und ver-XODERe die oberen 32 Bit mit den unteren.</p>
<p>Also eine Iteration über alle Elemente ist ja schon mal zwingend....obs noch schneller geht?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1383266</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1383266</guid><dc:creator><![CDATA[Mati]]></dc:creator><pubDate>Thu, 11 Oct 2007 21:46:11 GMT</pubDate></item><item><title><![CDATA[Reply to Hash_Key aus double-vector möglichst schnell: Ideen gesucht on Thu, 11 Oct 2007 22:57:05 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">typedef unsigned int U_Int32;

template &lt;&gt;    U_Int32
Cache&lt;double&gt;::Compute_Key(    const double* vec,
                            size_t size) const
{                    
    U_Int32 ret = 0;
    U_Int32 mix = Hash_Double(0.13);
    while(size--)
    {
        ret = (ret * 31) + mix + Hash_Double(*vec);
        vec++;
    }
    return ret;
}

template &lt;class T&gt;    inline U_Int32
Cache&lt;T&gt;::Hash_Double(const double&amp; x) // const double&amp; bei inlining evtl. effizienter
{
    //     U_Int64* p = reinterpret_cast&lt; U_Int64* &gt; (&amp;x);
    //     return *p ^ (*p &gt;&gt; 32);
    struct Helper
    {
        U_Int32 p[2];
    };
    const Helper&amp; h = *new(const_cast&lt;void*&gt;(&amp;x)) Helper; // tut eigentlich nichts, müsste aber unerlaubtes aliasing verhindern
    U_Int32 result = h.p[0] ^ h.p[1];
    new(const_cast&lt;void*&gt;(&amp;x)) double;
    return result;
}
</code></pre>
<p>Ich bin mir noch nicht ganz sicher ob das wirklich legal ist, aber ein Feldversuch kann nicht schaden.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1383290</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1383290</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 11 Oct 2007 22:57:05 GMT</pubDate></item><item><title><![CDATA[Reply to Hash_Key aus double-vector möglichst schnell: Ideen gesucht on Thu, 11 Oct 2007 22:59:34 GMT]]></title><description><![CDATA[<p>Warum nicht einfach so?</p>
<pre><code class="language-cpp">Hash_Double(const double&amp; x)
{
    struct Helper
    {
        U_Int32 a, b;
    };
    const Helper&amp; h = (const Helper&amp;)x;
    return h.a ^ h.b;
}
</code></pre>
]]></description><link>https://www.c-plusplus.net/forum/post/1383292</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1383292</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Thu, 11 Oct 2007 22:59:34 GMT</pubDate></item><item><title><![CDATA[Reply to Hash_Key aus double-vector möglichst schnell: Ideen gesucht on Thu, 11 Oct 2007 23:10:27 GMT]]></title><description><![CDATA[<p>Badestrand schrieb:</p>
<blockquote>
<p>Warum nicht einfach so?</p>
<pre><code class="language-cpp">Hash_Double(const double&amp; x)
{
    struct Helper
    {
        U_Int32 a, b;
    };
    const Helper&amp; h = (const Helper&amp;)x;
    return h.a ^ h.b;
}
</code></pre>
</blockquote>
<p>weil das Layout von Helper nicht hinreichend genau festgelegt ist (deshalb muss es mit einem Array sein). Was schwerer wiegt, ist die Verletzung der Aliasregeln. Seit Urzeiten werden Programme geschrieben, die diese Regeln verletzen, nicht zuletzt deshalb, weil die Compiler lange nicht in der Lage waren, das Optimierungspotential, das in diesen Regeln liegt, zu nutzen. Viele der Probleme, die bei hohen Optimierungsstufen auftreten, sind - abgesehen von echten Compilerfehlern - auf solche subtilen Fehler zurückzuführen.</p>
<blockquote>
<p>3.10<br />
15 If a program attempts to access the stored value of an object through an lvalue of other than one of the following types the behavior is undefined48):<br />
— the dynamic type of the object,<br />
— a cv-qualified version of the dynamic type of the object,<br />
— a type that is the signed or unsigned type corresponding to the dynamic type of the object,<br />
— a type that is the signed or unsigned type corresponding to a cv-qualified version of the dynamic type of the object,<br />
— an aggregate or union type that includes one of the aforementioned types among its members (including, recursively, a member of a subaggregate or contained union),<br />
— a type that is a (possibly cv-qualified) base class type of the dynamic type of the object,<br />
— a char or unsigned char type.</p>
<ol start="48">
<li>The intent of this list is to specify those circumstances in which an object may or may not be aliased.</li>
</ol>
</blockquote>
]]></description><link>https://www.c-plusplus.net/forum/post/1383297</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1383297</guid><dc:creator><![CDATA[camper]]></dc:creator><pubDate>Thu, 11 Oct 2007 23:10:27 GMT</pubDate></item><item><title><![CDATA[Reply to Hash_Key aus double-vector möglichst schnell: Ideen gesucht on Fri, 12 Oct 2007 04:41:03 GMT]]></title><description><![CDATA[<pre><code class="language-cpp">Hash_Double(const double&amp; x)
{
    U_Int32* a = reinterpret_cast&lt; U_Int32* &gt; (&amp;x);
    return *a ^ *(a+1);
}
</code></pre>
<p>so?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1383325</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1383325</guid><dc:creator><![CDATA[und]]></dc:creator><pubDate>Fri, 12 Oct 2007 04:41:03 GMT</pubDate></item><item><title><![CDATA[Reply to Hash_Key aus double-vector möglichst schnell: Ideen gesucht on Fri, 12 Oct 2007 09:54:09 GMT]]></title><description><![CDATA[<p>camper schrieb:</p>
<blockquote>
<p>Badestrand schrieb:</p>
<blockquote>
<p>...</p>
</blockquote>
<p>weil das Layout von Helper nicht hinreichend genau festgelegt ist (deshalb muss es mit einem Array sein). Was schwerer wiegt, ist die Verletzung der Aliasregeln.</p>
</blockquote>
<p>Kannst du das evtl ein wenig genauer erklären? Und wie meinst du das mit den Aliasregeln? Dass a und b auch 8-Byte-Aligned sein könnten?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1383554</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1383554</guid><dc:creator><![CDATA[Badestrand]]></dc:creator><pubDate>Fri, 12 Oct 2007 09:54:09 GMT</pubDate></item><item><title><![CDATA[Reply to Hash_Key aus double-vector möglichst schnell: Ideen gesucht on Sat, 13 Oct 2007 13:31:16 GMT]]></title><description><![CDATA[<p>Danke vielmals für eure Hilfe - leider schreit mein compiler gcc 4.1.3 mit der version von camper mehrmals nach einem ungültigen cast:</p>
<pre><code>Fehler: ungültiges const_cast von Typ »double*« in Typ »void*«
</code></pre>
<p>Ändere ich die cast von void* nach double* klappt natürlich. Und ich glaube auch dass es korrekt arbeitet - bemerke aber dass ich etwas langsamer bin mit dieser funktion...</p>
<p>Der reinterpret_cast ist zwar schneller liefert aber inkorrekte ergebnisse...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/1384380</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/1384380</guid><dc:creator><![CDATA[Mati]]></dc:creator><pubDate>Sat, 13 Oct 2007 13:31:16 GMT</pubDate></item></channel></rss>