<?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[shared_ptr performance &amp;amp; design Frage]]></title><description><![CDATA[<p>Ich brauche für eine eigene Datenstruktur spezielle shared_ptr - ähnliche smart pointer. Ich will zuerst eine nicht thread sichere Version, werde aber vielleicht in Zukunft auch eine thread sichere (so wie in boost/std) brauchen.<br />
Ich habe jetzt zwei Fragen:</p>
<p>1. Interface<br />
Haltet ihr es für sinnvoll, dass man auch für diesen ptr ein <code>= NULL</code> anbietet? Ich würde das ganze so umsetzen:</p>
<pre><code class="language-cpp">class ptr
{
private:
    class dummy;
public:
    ptr( dummy * )
    {
        //ptr auf NULL Zustand setzen
    }
};
///////////////////////
ptr p = 0;
</code></pre>
<p>Die einzige Möglichkeit, die ich sehe, sowas auszutricksen wäre</p>
<pre><code class="language-cpp">class trick
{
public:
    template&lt; class Type &gt;
    operator Type*();
};
</code></pre>
<p>2. Performance und NULL<br />
Wie soll man ein NULL-Wert handhaben? Ich sehe 2 Möglichkeiten:<br />
a) einfach den internen rohen Zeiger auf NULL setzen. Nachteil: Beim Zerstören braucht man immer zusätzlich ein <code>if( m_ptr )</code> , um auch auf einen gültigen ref count zuzugreifen.<br />
b) Den rohen Zeiger auf ein Dummy Objekt zeigen lassen. Nachteil: Auch beim moven muss der ref count angetastet werden (sehe hier vor allem Probleme bei multithreading, wobei bei mir Zugriff auf ein std::atomic &quot;nur&quot; doppelt so lang braucht wie auf einen normalen int).</p>
]]></description><link>https://www.c-plusplus.net/forum/topic/294966/shared_ptr-performance-amp-design-frage</link><generator>RSS for Node</generator><lastBuildDate>Sat, 15 Aug 2026 15:43:39 GMT</lastBuildDate><atom:link href="https://www.c-plusplus.net/forum/topic/294966.rss" rel="self" type="application/rss+xml"/><pubDate>Fri, 04 Nov 2011 16:23:31 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to shared_ptr performance &amp;amp; design Frage on Fri, 04 Nov 2011 16:23:31 GMT]]></title><description><![CDATA[<p>Ich brauche für eine eigene Datenstruktur spezielle shared_ptr - ähnliche smart pointer. Ich will zuerst eine nicht thread sichere Version, werde aber vielleicht in Zukunft auch eine thread sichere (so wie in boost/std) brauchen.<br />
Ich habe jetzt zwei Fragen:</p>
<p>1. Interface<br />
Haltet ihr es für sinnvoll, dass man auch für diesen ptr ein <code>= NULL</code> anbietet? Ich würde das ganze so umsetzen:</p>
<pre><code class="language-cpp">class ptr
{
private:
    class dummy;
public:
    ptr( dummy * )
    {
        //ptr auf NULL Zustand setzen
    }
};
///////////////////////
ptr p = 0;
</code></pre>
<p>Die einzige Möglichkeit, die ich sehe, sowas auszutricksen wäre</p>
<pre><code class="language-cpp">class trick
{
public:
    template&lt; class Type &gt;
    operator Type*();
};
</code></pre>
<p>2. Performance und NULL<br />
Wie soll man ein NULL-Wert handhaben? Ich sehe 2 Möglichkeiten:<br />
a) einfach den internen rohen Zeiger auf NULL setzen. Nachteil: Beim Zerstören braucht man immer zusätzlich ein <code>if( m_ptr )</code> , um auch auf einen gültigen ref count zuzugreifen.<br />
b) Den rohen Zeiger auf ein Dummy Objekt zeigen lassen. Nachteil: Auch beim moven muss der ref count angetastet werden (sehe hier vor allem Probleme bei multithreading, wobei bei mir Zugriff auf ein std::atomic &quot;nur&quot; doppelt so lang braucht wie auf einen normalen int).</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140300</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140300</guid><dc:creator><![CDATA[GorbGorb]]></dc:creator><pubDate>Fri, 04 Nov 2011 16:23:31 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr performance &amp;amp; design Frage on Fri, 04 Nov 2011 16:34:32 GMT]]></title><description><![CDATA[<p>Sinnvoll ist, was sich natürlich anfühlt. Orientiere dich doch am boost shared_ptr, und versuche, deine eigene Semantik möglichst gleich zu kapseln. Was hast du denn vor?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140303</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140303</guid><dc:creator><![CDATA[*rant*]]></dc:creator><pubDate>Fri, 04 Nov 2011 16:34:32 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr performance &amp;amp; design Frage on Fri, 04 Nov 2011 16:39:40 GMT]]></title><description><![CDATA[<p>Bevor du sowas bastelst, würd ich mir mal überlegen, ob ich das wirklich will. Shared-Ownership will man meiner Erfahrung nach nämlich eigentlich eher selten, wenn man ganz ehrlich ist...</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140306</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140306</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Fri, 04 Nov 2011 16:39:40 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr performance &amp;amp; design Frage on Fri, 04 Nov 2011 17:08:56 GMT]]></title><description><![CDATA[<p>ad 1) halte ich nicht für sinnvoll</p>
<p>ad 2) &quot;=&quot; auf ein atomic mag schnell sein, &quot;+=&quot; aber sicher nicht. bei x86/AMD64 CPUs dauert das ca. 100x so lange wie ohne &quot;atomic&quot;. zumindest in der grössenordnung, soll sein 25x oder 400x - auf jeden fall nicht 2x.<br />
und: ich würde den zeiger einfach auf NULL setzen.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140324</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140324</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 04 Nov 2011 17:08:56 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr performance &amp;amp; design Frage on Fri, 04 Nov 2011 18:45:54 GMT]]></title><description><![CDATA[<p>dot schrieb:</p>
<blockquote>
<p>Shared-Ownership will man meiner Erfahrung nach nämlich eigentlich eher selten, wenn man ganz ehrlich ist...</p>
</blockquote>
<p>Wenn ich kein C++11 &quot;move&quot; habe, dann will ich zumindest das ziemlich oft.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140396</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140396</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 04 Nov 2011 18:45:54 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr performance &amp;amp; design Frage on Fri, 04 Nov 2011 18:47:53 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>dot schrieb:</p>
<blockquote>
<p>Shared-Ownership will man meiner Erfahrung nach nämlich eigentlich eher selten, wenn man ganz ehrlich ist...</p>
</blockquote>
<p>Wenn ich kein C++11 &quot;move&quot; habe, dann will ich zumindest das ziemlich oft.</p>
</blockquote>
<p>Ich nicht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140400</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140400</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Fri, 04 Nov 2011 18:47:53 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr performance &amp;amp; design Frage on Fri, 04 Nov 2011 19:33:14 GMT]]></title><description><![CDATA[<p>Seltsam<br />
<img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f615.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--confused_face"
      title=":confused:"
      alt="😕"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140438</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140438</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Fri, 04 Nov 2011 19:33:14 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr performance &amp;amp; design Frage on Fri, 04 Nov 2011 21:10:45 GMT]]></title><description><![CDATA[<p>Wenn ihr beide (hustbear und dot) beide nicht so extrem wortkarg wärt, könnte daraus noch eine Interessante Diskussion werden! Also her mit den ausführlichen Antworten und Argumenten! Das mach dies noch explzit erwähnen muss <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
<p>Grüssli</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140496</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140496</guid><dc:creator><![CDATA[Dravere]]></dc:creator><pubDate>Fri, 04 Nov 2011 21:10:45 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr performance &amp;amp; design Frage on Fri, 04 Nov 2011 21:17:46 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p>ad 1) halte ich nicht für sinnvoll</p>
<p>ad 2) &quot;=&quot; auf ein atomic mag schnell sein, &quot;+=&quot; aber sicher nicht. bei x86/AMD64 CPUs dauert das ca. 100x so lange wie ohne &quot;atomic&quot;. zumindest in der grössenordnung, soll sein 25x oder 400x - auf jeden fall nicht 2x.<br />
und: ich würde den zeiger einfach auf NULL setzen.</p>
</blockquote>
<p>Bei mir braucht += doppelt solange, wenn nur 1 thread gleichzeitig auf das atomic zugreift. Sonst steigt es sehr stark an auf die Größenordnungen die du genannt hast. Ich denke ich werde mal beides ausprobieren, ein kleines real-world Programm schreiben und dann mal schauen, was schneller ist.<br />
Warum hältst du 1) nicht für sinnvoll? Es würde das interface des pointers doch noch mehr an das eines normalen pointers annähern.</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140498</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140498</guid><dc:creator><![CDATA[GorbGorb]]></dc:creator><pubDate>Fri, 04 Nov 2011 21:17:46 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr performance &amp;amp; design Frage on Fri, 04 Nov 2011 22:24:55 GMT]]></title><description><![CDATA[<p>Dravere schrieb:</p>
<blockquote>
<p>Wenn ihr beide (hustbear und dot) beide nicht so extrem wortkarg wärt, könnte daraus noch eine Interessante Diskussion werden! Also her mit den ausführlichen Antworten und Argumenten! Das mach dies noch explzit erwähnen muss <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f603.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--grinning_face_with_big_eyes"
      title=":D"
      alt="😃"
    /></p>
</blockquote>
<p>Naja, ich find die meisten shared_ptr, die ich bisher so gesehen hab, waren eigentlich nur eine Art zu sagen: &quot;Ich hab keine Ahnung was für einen Scope dieses Objekt eigentlich hat und will mir auch keine Gedanken drüber machen.&quot;<br />
shared_ptr widerspricht imo schon in seiner Natur ein wenig der essentiellen Idee von RAII, dessen Ausdruck ein Smartpointer doch eigentlich sein sollte!?<br />
Shared Ownership hat sicherlich ihren Platz, aber imo sind das eher Randbereiche und Ausnahmefälle. Ich find, dass es sehr wesentlich für gutes Design ist, sich darüber im Klaren zu sein, welche Objekte andere Objekte nur <em>verwenden</em> und welche Objekte sie tatsächlich <em>besitzen</em> und diese Beziehungen auch entsprechend im Design zu reflektieren. Und meiner Erfahrung nach lässt sich die Besitzbeziehung praktisch immer auf genau ein anderes Objekt festnageln.<br />
Wenn ich ein Objekt in meinem Programm hätte, dessen Scope ich nicht genau definieren kann, dann würd ich das zumindest mal gründlich hinterfragen, anstatt einfach shared_ptr und gut ist. Beispiel Dependency-Injection. Ich find, dass das, was heute unter &quot;Dependency-Injection&quot; läuft, eigentlich nix andres ist, als ein Aspekt der reinen Lehre von RAII. In so einem Design ergibt sich rein systematisch bedingt für jedes Objekt praktisch immer und völlig natürlich ein ganz eindeutiger Scope.<br />
Genau aus oben genannten Gründen halte ich auch Dinge wie z.B. Garbage Collection für überhaupt nicht förderlich für gutes Design. Garbage Collection belohnt schlechtes Design ohne gutes Design auch nur in irgendeiner Form zu unterstützen. In einem sehr guten Design wären die Objektbeziehungen imo von vornherein so klar, dass Garbage Collection sinnlos wird.</p>
<p>EDIT: Die Tatsache, dass ich in meiner Philosophie eigentlich nicht wirklich zwischen Scope und Lifetime unterscheide, ist nur ein weiterer Ausdruck dessen, worums mir hier eigentlich geht <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140502</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140502</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Fri, 04 Nov 2011 22:24:55 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr performance &amp;amp; design Frage on Sat, 05 Nov 2011 03:25:38 GMT]]></title><description><![CDATA[<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/26958">@GorbGorb</a>:<br />
Ich würde 1) nicht machen, weil ... weiss nicht. Stört mich einfach nicht dass ich .reset() schreiben muss.<br />
Zu 2x vs. 100x: mit was für einer CPU testest du das? P4 und Core2 brauchen<br />
, wenn mich meine Erinnerung jetzt nicht trügt, so ca. 400 Cycles für ein InterlockedIncrement (wohingegen ein normales so bei 0,3-1 Cycles liegt).</p>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6496">@dot</a><br />
Wie machst du Ownership-Transfer ohne move und ohne shared_ptr?<br />
scoped_ptr&amp; übergeben und swap?<br />
Das fände ich hässlich, aber immer noch akzeptabel.<br />
Oder .release() und rohe Zeiger übergeben? Sowas würde ich nichtmal mit der Kneifzange angreifen, weil man viel zu sehr aufpassen muss, dass der Code dann 100% Exception-safe ist (=nicht leakt, egal wann wo was rausfliegt).</p>
<p>Und was machst du, wenn man eine Klasse mal mit Ownership-Transfer und mal ohne verwenden will?</p>
<p>Was mich an der unique Ownership Variante auch stört: es gibt keine &quot;checked&quot; Variante. Oft genug muss man Zeiger &quot;ausborgen&quot;, und wenn die dann verwendet werden nachdem das Objekt bereits zerstört wurde, dann ist die Kacke am dampfen. Dann crasht der Prozess. Oder auch nicht. UB vom feinsten. Wenn man da wenigstens ne Exception bekommen könnte, sähe die Sache schon ganz anders aus.</p>
<p>Und noch eine Frage: kann es sein, dass du oft bis immer irgendwelche Business-Logik-Dingens implementierst, und selten bis nie mit z.B. GUI Anwendungen zu tun hast? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140554</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140554</guid><dc:creator><![CDATA[hustbaer]]></dc:creator><pubDate>Sat, 05 Nov 2011 03:25:38 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr performance &amp;amp; design Frage on Sat, 05 Nov 2011 09:58:00 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/6496">@dot</a><br />
Wie machst du Ownership-Transfer ohne move und ohne shared_ptr?<br />
scoped_ptr&amp; übergeben und swap?</p>
</blockquote>
<p>auto_ptr? Brauch ich aber auch erstaunlich selten, eigentlich nie. Nach ein paar Refactorings sind solche Konstrukte bei mir bisher praktisch immer irgendwie verschwunden...<br />
Ein scoped_ptr ist sicherlich bei weitem die häufigste Art von Smartpointer die ich verwend.</p>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Und was machst du, wenn man eine Klasse mal mit Ownership-Transfer und mal ohne verwenden will?</p>
</blockquote>
<p>Versteh das Problem nicht ganz. Wie ich meine Objekte instanzier, betrifft die Klasse doch in keiner Weise, das würde doch gegen das Single Responsibility Principle verstoßen!?</p>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Was mich an der unique Ownership Variante auch stört: es gibt keine &quot;checked&quot; Variante. Oft genug muss man Zeiger &quot;ausborgen&quot;, und wenn die dann verwendet werden nachdem das Objekt bereits zerstört wurde, dann ist die Kacke am dampfen. Dann crasht der Prozess. Oder auch nicht. UB vom feinsten. Wenn man da wenigstens ne Exception bekommen könnte, sähe die Sache schon ganz anders aus.</p>
</blockquote>
<p>Das kann natürlich passieren, aber passiert mir eher selten und wenn, dann hab ich ja nen Debugger <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /><br />
Wenn du wirklich Angst davor hast, kannst du ja statt roher Zeiger irgendeine Art von Weak-Reference verwenden...</p>
<p>hustbaer schrieb:</p>
<blockquote>
<p>Und noch eine Frage: kann es sein, dass du oft bis immer irgendwelche Business-Logik-Dingens implementierst, und selten bis nie mit z.B. GUI Anwendungen zu tun hast? <img
      src="https://www.c-plusplus.net/forum/plugins/nodebb-plugin-emoji/emoji/emoji-one/1f609.png?v=ab1pehoraso"
      class="not-responsive emoji emoji-emoji-one emoji--winking_face"
      title=";)"
      alt="😉"
    /></p>
</blockquote>
<p>Nö, eigentlich nicht. Die meiste Zeit schreib ich irgendwelche Grafikanwendungen, mein letzter Freelance-Job war ein CAD-Tool mit GUI und gerade unlängst hab ich überhaupt ein kleines GUI-System an sich gebaut. Mir würd spontan jetzt kein Grund einfallen, wieso eine GUI so prädestiniert für Shared-Ownership sein sollte. <em>Gerade</em> bei einer GUI, die ja in ihrer Natur schon eine reine Baumstruktur ist, wo jedes Element genau einen Parent hat, sind die Besitzbeziehungen doch extrem eindeutig!?</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140593</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140593</guid><dc:creator><![CDATA[dot]]></dc:creator><pubDate>Sat, 05 Nov 2011 09:58:00 GMT</pubDate></item><item><title><![CDATA[Reply to shared_ptr performance &amp;amp; design Frage on Sat, 05 Nov 2011 10:13:07 GMT]]></title><description><![CDATA[<p>hustbaer schrieb:</p>
<blockquote>
<p><a class="plugin-mentions-user plugin-mentions-a" href="https://www.c-plusplus.net/forum/uid/26958">@GorbGorb</a>:<br />
Ich würde 1) nicht machen, weil ... weiss nicht. Stört mich einfach nicht dass ich .reset() schreiben muss.<br />
Zu 2x vs. 100x: mit was für einer CPU testest du das? P4 und Core2 brauchen<br />
, wenn mich meine Erinnerung jetzt nicht trügt, so ca. 400 Cycles für ein InterlockedIncrement (wohingegen ein normales so bei 0,3-1 Cycles liegt).</p>
</blockquote>
<p>Ich benutze einen Core i5. Das ist der code, mit dem ich es getestet habe:</p>
<pre><code class="language-cpp">#include &lt;iostream&gt;
#include &lt;ctime&gt;

#include &lt;atomic&gt;
#include &lt;boost/thread.hpp&gt;

template&lt; class A &gt;
void measure( const char *name , A &amp;&amp;functor_a )
{
	unsigned int t = std::clock();
	boost::thread thread_a( functor_a );
	thread_a.join();
	std::cout &lt;&lt; name &lt;&lt; std::clock() - t &lt;&lt; std::endl;
}
template&lt; class A , class B &gt;
void measure( const char *name , A &amp;&amp;functor_a , B &amp;&amp;functor_b )
{
	unsigned int t = std::clock();
	boost::thread thread_a( functor_a );
	boost::thread thread_b( functor_b );
	thread_a.join();
	thread_b.join();
	std::cout &lt;&lt; name &lt;&lt; std::clock() - t &lt;&lt; std::endl;
}

std::atomic&lt; int &gt; a( 0 );
volatile unsigned int n1 = 0;
volatile unsigned int n2 = 0;
volatile unsigned int volatile_test = 0;
const unsigned int loop_number = 20000;

int main()
{
	auto threadfunc_a = []()
	{
		for( unsigned int i = 0 ; i &lt; loop_number ; ++i )
		{
			a.fetch_sub(1, std::memory_order_release);
			a.fetch_sub(1, std::memory_order_release);
			a.fetch_sub(1, std::memory_order_release);
			a.fetch_sub(1, std::memory_order_release);
			a.fetch_sub(1, std::memory_order_release);
			a.fetch_sub(1, std::memory_order_release);
			a.fetch_sub(1, std::memory_order_release);
			a.fetch_sub(1, std::memory_order_release);
		}
	};

	auto threadfunc_n1 = []()
	{
		for( unsigned int i = 0 ; i &lt; loop_number ; ++i )
		{
			--n1;
			--n1;
			--n1;
			--n1;
			--n1;
			--n1;
			--n1;
			--n1;
		}
	};

	auto threadfunc_n2 = []()
	{
		for( unsigned int i = 0 ; i &lt; loop_number ; ++i )
		{
			--n2;
			--n2;
			--n2;
			--n2;
			--n2;
			--n2;
			--n2;
			--n2;
		}
	};

	auto threadfunc_volatile_test = []()
	{
		for( unsigned int i = 0 ; i &lt; loop_number ; ++i )
			--volatile_test;
	};

	measure( &quot;atomic 1 thread: &quot; , threadfunc_a );
	measure( &quot;volatile 1 thread: &quot; , threadfunc_n1 );
	measure( &quot;volatile test 1 thread: &quot; , threadfunc_volatile_test );

	measure( &quot;atomic 2 threads: &quot; , threadfunc_a , threadfunc_a );
	measure( &quot;volatile 2 threads: &quot; , threadfunc_n1 , threadfunc_n2 );

	std::cin.get();
	return 0;
}
</code></pre>
<p>Was mich daran ernsthaft beunruhigt, ist, dass sich das Programm ab loopnumber ~ 10000 regelmäßig aufhängt... Woran könnte das liegen?</p>
<p>Ausgabe mit loopnumber = 20000:<br />
atomic 1 thread: 4<br />
volatile 1 thread: 1<br />
single volatile 1 thread: 1<br />
atomic 2 threads: 7<br />
volatile 2 threads: 4</p>
<p>Damit kann man leider nicht allzu viel anfangen, std::clock() ist ja nicht besonders genau...<br />
Die Ausgabe bei loopnumber = 10000000, soweit es eben gekommen ist:<br />
atomic 1 thread: 1018<br />
volatile 1 thread: 425<br />
volatile test 1 thread: 52</p>
]]></description><link>https://www.c-plusplus.net/forum/post/2140597</link><guid isPermaLink="true">https://www.c-plusplus.net/forum/post/2140597</guid><dc:creator><![CDATA[GorbGorb]]></dc:creator><pubDate>Sat, 05 Nov 2011 10:13:07 GMT</pubDate></item></channel></rss>