<?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>Fiber Pool</title>
	<atom:link href="http://blog.thinkmeta.de/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.thinkmeta.de</link>
	<description>Multicore Task Scheduler</description>
	<lastBuildDate>Sun, 18 Jul 2010 16:55:17 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Patentanmeldung offengelegt</title>
		<link>http://blog.thinkmeta.de/2010/07/patentanmeldung-offengelegt/</link>
		<comments>http://blog.thinkmeta.de/2010/07/patentanmeldung-offengelegt/#comments</comments>
		<pubDate>Sun, 18 Jul 2010 16:55:17 +0000</pubDate>
		<dc:creator>gk</dc:creator>
				<category><![CDATA[Allgemeines]]></category>
		<category><![CDATA[Fiber Pool]]></category>

		<guid isPermaLink="false">http://blog.thinkmeta.de/?p=212</guid>
		<description><![CDATA[<p>Seit letztem Monat ist die Patentanmeldung mit dem Titel &#8220;Scheduling bei Mehrkernprozessoren&#8221; vom Deutschen Patent- und Markenamt (DPMA) offengelegt worden.</p>
<p>Das dafür bereitgestellte PDF-Dokument kann unter Angabe der Anmeldenummer &#8220;102008060505&#8243; [...]]]></description>
			<content:encoded><![CDATA[<p>Seit letztem Monat ist die Patentanmeldung mit dem Titel &#8220;Scheduling bei Mehrkernprozessoren&#8221; vom <a href="http://www.dpma.de">Deutschen Patent- und Markenamt (DPMA)</a> offengelegt worden.</p>
<p>Das dafür bereitgestellte PDF-Dokument kann unter Angabe der Anmeldenummer &#8220;102008060505&#8243; gefunden werden.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinkmeta.de/2010/07/patentanmeldung-offengelegt/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Das Ende naht&#8230;</title>
		<link>http://blog.thinkmeta.de/2010/03/das-ende-naht/</link>
		<comments>http://blog.thinkmeta.de/2010/03/das-ende-naht/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 13:40:12 +0000</pubDate>
		<dc:creator>gk</dc:creator>
				<category><![CDATA[Allgemeines]]></category>
		<category><![CDATA[Fiber Pool]]></category>

		<guid isPermaLink="false">http://blog.thinkmeta.de/?p=210</guid>
		<description><![CDATA[<p>Hallo allerseits,</p>
<p>aktuell arbeite ich an einer dringend notwendigen neuen Dokumentation für Fiber Pool. Da leider die Zeit für Übersetzungen fehlt und vieles aus dem Source Code halbautomatisch in die Doku fließt, habe ich beschlossen, alles nur noch in Englisch zu verfassen.</p>
<p>Konsequenterweise werde ich auch diesen Blog in deutscher Sprache bald nicht mehr weiterpflegen und meine Gedanken [...]]]></description>
			<content:encoded><![CDATA[<p>Hallo allerseits,</p>
<p>aktuell arbeite ich an einer dringend notwendigen neuen Dokumentation für Fiber Pool. Da leider die Zeit für Übersetzungen fehlt und vieles aus dem Source Code halbautomatisch in die Doku fließt, habe ich beschlossen, alles nur noch in Englisch zu verfassen.</p>
<p>Konsequenterweise werde ich auch diesen Blog in deutscher Sprache bald nicht mehr weiterpflegen und meine Gedanken zukünftig in hoffentlich verständlichem Englisch (hängt vom Online-Übersetzer ab <img src='http://blog.thinkmeta.de/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> ) wiedergeben&#8230;</p>
<p>Gruß<br />
George</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinkmeta.de/2010/03/das-ende-naht/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DirectShow und USB: Die richtigen Capture-Filter ermitteln</title>
		<link>http://blog.thinkmeta.de/2010/03/directshow-und-usb-die-richtigen-capture-filter-ermitteln/</link>
		<comments>http://blog.thinkmeta.de/2010/03/directshow-und-usb-die-richtigen-capture-filter-ermitteln/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 07:05:17 +0000</pubDate>
		<dc:creator>gk</dc:creator>
				<category><![CDATA[DirectShow]]></category>

		<guid isPermaLink="false">http://blog.thinkmeta.de/?p=199</guid>
		<description><![CDATA[<p>Beim Capturen von USB-Geräten mit DirectShow werden Video und Audio meist separat von zwei verschiedenen Filtern eingelesen. Der Grund dafür, dass zwei und nicht ein Filter nötig sind, liegt am USB-Klassenmodell (es gibt je eine Klasse für Video und Audio) und den dazu entsprechenden Treiberschnittstellen, die vom System zur Verfügung gestellt werden. DirectShow bietet jedoch keine [...]]]></description>
			<content:encoded><![CDATA[<p>Beim Capturen von USB-Geräten mit DirectShow werden Video und Audio meist separat von zwei verschiedenen Filtern eingelesen. Der Grund dafür, dass zwei und nicht ein Filter nötig sind, liegt am USB-Klassenmodell (es gibt je eine Klasse für Video und Audio) und den dazu entsprechenden Treiberschnittstellen, die vom System zur Verfügung gestellt werden. DirectShow bietet jedoch keine Funktion oder Methode an, mit der man die gemeinsamen Filter eines Capture-Geräts ermitteln könnte.</p>
<p>Mit ein bisschen Know-How kann man aber so eine Funktion selbst implementieren. Wie das geht, möchte ich Euch heute zeigen. Für den Artikel setze ich voraus, dass Ihr Euch schon einige Zeit mit DirectShow beschäftigt habt. Daher werde ich nicht bei 0 beginnen.</p>
<p><strong>1. Auflisten der Video-Capture-Filter</strong></p>
<p>Zunächst erzeugen wir eine Liste der verfügbaren Video-Capture-Filter mittels <code>IEnumMoniker</code> und <code>CLSID_VideoInputDeviceCategory</code>.</p>
<p>Während der Auflistung sichern wir uns für jeden IMoniker seinen &#8220;Display Name&#8221;. Wir entfernen jedoch das vorangestellte &#8220;@device:pnp:&#8221; und erhalten somit den Pfad auf das Gerät, den man z.B. in <code>CreateFile</code> verwenden könnte.</p>
<p><strong>2. Auflisten der Audio-Capture-Filter</strong></p>
<p>Ähnlich verfahren wir mit den Audio-Capture-Filtern mittels <code>CLSID_AudioInputCategory</code>.</p>
<p>Beim &#8220;Display Name&#8221; wird das vorangestellte &#8220;@device:cm:{33D9A762-90C8-11D0-BD43-00A0C911CE86}\&#8221; entfernt. Daraus erhalten wir jedoch noch nicht den Pfad zum Gerät. Den müssen wir als Nächstes ermitteln.</p>
<p><strong>3. Auflisten der waveInxxx-Geräte</strong></p>
<p>Mittels dem waveInxxx-API werden nun alle Audio-Capture-Geräte aufgelistet. Deren Anzahl erhält man über die <code>waveInGetNumDevs</code>-Funktion.</p>
<p>Über <code>waveInGetDevCaps</code> erhält man den Namen des Geräts im Struktur-Member <code>WAVEINCAPS.szPname</code>. Über einen String-Vergleich erhalten wir somit eine Verbindung zu seinem Audio-Capture-Filter.</p>
<p>Jetzt können wir für den jeweiligen Filter den Gerätepfad ermitteln. Dies machen wir mit <code>waveInMessage</code> und den Nachrichten <code>DRV_QUERYDEVICEINTERFACESIZE</code> und <code>DRV_QUERYDEVICEINTERFACE</code>.</p>
<p><strong>4. Ermitteln der Geräte-Instanz</strong></p>
<p>Für jeden gefundenen Gerätepfad (Video und Audio) müssen wir jetzt nur noch seine Geräte-Instanz ermitteln. Dies machen wir über das Setup API:</p>
<p>Zuerst holen wir uns eine Liste von Geräteinformationen über <code>SetupDiGetClassDevs</code>. Für Video vewenden wir als Kategorie <code>KSCATEGORY_CAPTURE</code> und für Audio <code>KSCATEGORY_AUDIO</code>.</p>
<p>Beim Durchgehen der zur Kategorie vorhandenen Geräteschnittstellen mittels <code>SetupDiEnumDeviceInterfaces</code> holen wir uns mit <code>SetupDiGetDeviceInterfaceDetail</code> Informationen über jede einzelne Schnittstelle.</p>
<p>Stimmt der Pfad in <code>SP_DEVICE_INTERFACE_DETAIL_DATA.DevicePath</code> mit einem unserer gespeicherten Pfade überein, so finden wir die Geräte-Instanz in <code>SP_DEVINFO_DATA.devInst</code> und können sie speichern.</p>
<p><strong>5. Die übergeordnete Geräte-Instanz ermitteln</strong></p>
<p>Im letzten Schritt wird für jede gefundene Geräte-Instanz ihre übergeordnete Geräte-Instanz ermittelt. Das machen wir mit der <code>CM_Get_Parent</code>-Funktion aus dem Configuration Manager API.</p>
<p>Findet man für Video und Audio diesselbe übergeordnete Geräte-Instanz, dann hat mein das Filter-Paar für ein Gerät gefunden! Fertig!</p>
<p>Das hört sich alles sehr kompliziert und aufwändig an, ist es aber nicht. Angehängt findet Ihr Beispielcode dazu, der kürzer als dieser Artikel ist!</p>
<p>Download:<br />
<a href='http://blog.thinkmeta.de/wp-content/uploads/2010/03/CaptureDevice.zip'>CaptureDevice.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinkmeta.de/2010/03/directshow-und-usb-die-richtigen-capture-filter-ermitteln/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sockets mit Fiber Pool</title>
		<link>http://blog.thinkmeta.de/2010/02/sockets-mit-fiber-pool/</link>
		<comments>http://blog.thinkmeta.de/2010/02/sockets-mit-fiber-pool/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 13:02:56 +0000</pubDate>
		<dc:creator>gk</dc:creator>
				<category><![CDATA[Fiber Pool]]></category>

		<guid isPermaLink="false">http://blog.thinkmeta.de/?p=196</guid>
		<description><![CDATA[<p>Hallo,</p>
<p>ab heute ist Fiber Pool 1.0.0.21 verfügbar. Der Download ist wie immer über die übliche Seite möglich.</p>
<p>Neben einigen kleinen Features und Bugfixes bietet das Fiber Pool API nun auch eine (ausbaufähige) Socket-Klasse an, mit der man hochperformante Netzwerkanwendungen entwickeln kann.</p>
<p>Als &#8220;kleines&#8221; Sample dazu habe ich einen einfachen HTTP-Server bereitgestellt, der gleichzeitig auf mehreren Adressen auf Anfragen [...]]]></description>
			<content:encoded><![CDATA[<p>Hallo,</p>
<p>ab heute ist Fiber Pool 1.0.0.21 verfügbar. Der Download ist wie immer über die übliche Seite möglich.</p>
<p>Neben einigen kleinen Features und Bugfixes bietet das Fiber Pool API nun auch eine (ausbaufähige) Socket-Klasse an, mit der man hochperformante Netzwerkanwendungen entwickeln kann.</p>
<p>Als &#8220;kleines&#8221; Sample dazu habe ich einen einfachen HTTP-Server bereitgestellt, der gleichzeitig auf mehreren Adressen auf Anfragen reagieren kann und für jede Adresse mehrere virtuelle Server unterstützt.<br />
Das HTTP-Protokoll Version 1.1 wird unterstützt, sodass Request-Pipelining möglich ist. Requests und Responses werden asynchron von den verfügbaren Prozessoren bearbeitet.<br />
Aktuell werden zwar nur statische Seiten übertragen, sodass hauptsächlich der File I/O Scheduler zum Tragen kommt, evtl. kommt aber später noch eine Serverskriptsprache (z.B. PHP) hinzu, bei der die Prozessoren dann tatsächlich etwas zu tun kriegen.</p>
<p>Zu FLAC wollte ich eigentlich auch eine hybride CPU/GPU-Version herausbringen, allerdings hat das zeitlich nicht hingehauen. Ob es sie jemals geben wird, wird die (viel zu wenige) Zeit zeigen&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinkmeta.de/2010/02/sockets-mit-fiber-pool/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Eulersche Zahl e &#8220;einfach&#8221; unendlich genau berechnen</title>
		<link>http://blog.thinkmeta.de/2010/02/eulersche-zahl-e-einfach-unendlich-genau-berechnen/</link>
		<comments>http://blog.thinkmeta.de/2010/02/eulersche-zahl-e-einfach-unendlich-genau-berechnen/#comments</comments>
		<pubDate>Tue, 16 Feb 2010 11:02:40 +0000</pubDate>
		<dc:creator>gk</dc:creator>
				<category><![CDATA[Mathematik]]></category>

		<guid isPermaLink="false">http://blog.thinkmeta.de/?p=168</guid>
		<description><![CDATA[<p>Ich hatte es beim Start dieses Blogs angekündigt und heute wird es wahr: Der erste Artikel zur Mathematik!</p>
<p>Ich möchte mit einem Algorithmus beginnen, mit dem man auf sehr einfache Weise die Eulersche Zahl e mit einem Computer genau berechnen kann. Als Rechenoperationen werden lediglich die Integer-Addition und die Shift-Operation benötigt.</p>
<p>Die Formel:
Eine einfache Berechnung benötigt eine einfache [...]]]></description>
			<content:encoded><![CDATA[<p>Ich hatte es beim Start dieses Blogs angekündigt und heute wird es wahr: Der erste Artikel zur Mathematik!</p>
<p>Ich möchte mit einem Algorithmus beginnen, mit dem man auf sehr einfache Weise die Eulersche Zahl e mit einem Computer genau berechnen kann. Als Rechenoperationen werden lediglich die Integer-Addition und die Shift-Operation benötigt.</p>
<p><strong>Die Formel:</strong><br />
Eine einfache Berechnung benötigt eine einfache Formel, und da Computer am liebsten mit Binärzahlen arbeiten, sollte die Formel dafür ausgelegt sein.</p>
<p>Man muss nicht lange nach so einer Formel suchen, denn es genügt, die Formel zur Berechnung von e, die wir aus der Schulmathematik kennen, nur leicht abzuwandeln, und zwar wie folgt:<br />
<a href="http://blog.thinkmeta.de/wp-content/uploads/2010/02/euler.png"><img src="http://blog.thinkmeta.de/wp-content/uploads/2010/02/euler.png" alt="" title="Euler" width="196" height="75" class="aligncenter size-full wp-image-169" /></a><br />
Durch die Verwendung von 2<sup>n</sup> statt n, erhält man nun für ein beliebiges n immer einen Binärbruch als Basis und somit eine Zahl, die der Computer mag.</p>
<p><strong>Die Dimensionen:</strong><br />
Der Basisbruch benötigt 1 Bit vor dem Komma und n Bits dahinter.</p>
<p>Da wir bereits wissen, dass e eine 2 vor dem Komma hat, wird das Ergebnis vor dem Komma zwei Bits benötigen.</p>
<p>Die Anzahl der Bits hinter dem Komma wird sich jedoch mit jeder Quadrierung verdoppeln. Und da n Quadrierungen durchgeführt werden müssen, lässt sich die Gesamtanzahl an Bits mit folgender Formel berechnen:<br />
<a href="http://blog.thinkmeta.de/wp-content/uploads/2010/02/euler_bits.png"><img src="http://blog.thinkmeta.de/wp-content/uploads/2010/02/euler_bits.png" alt="" title="Euler Bits" width="204" height="46" class="aligncenter size-full wp-image-173" /></a><br />
Für n=10 benötigt man etwa 10 kbits, für n=20 21 Mbits, für n=30 32 Gbits, für n=35 1,2 TBits und für n=58 (der maximale Wert bei 64-Bit-Adressierung) schlappe 16,7 Ebits (Exabits).</p>
<p><strong>Der Algorithmus:</strong><br />
Das Quadrieren im Binärformat ist einfach. Betrachten wir dazu zunächst den allgemeinen Fall:<br />
<a href="http://blog.thinkmeta.de/wp-content/uploads/2010/02/euler3.png"><img src="http://blog.thinkmeta.de/wp-content/uploads/2010/02/euler3.png" alt="" title="Quadrieren allgemein" width="465" height="39" class="aligncenter size-full wp-image-176" /></a><br />
Man sieht, dass alle Summanden quadriert werden und zusätzlich alle Summanden paarweise miteinander multipliziert werden. Letztere Operation kommt beim Ausmultiplizieren zweimal vor, daher die 2 an jedem Term.</p>
<p>Übertragen auf eine Binärzahl, erhalten wir z.B.<br />
<a href="http://blog.thinkmeta.de/wp-content/uploads/2010/02/euler4.png"><img src="http://blog.thinkmeta.de/wp-content/uploads/2010/02/euler4.png" alt="" title="Quadrieren - Binär" width="697" height="43" class="aligncenter size-full wp-image-177" /></a><br />
Daraus können wir zwei Operationen für das Quadrieren ableiten:</p>
<p>1. Ist Bit n im Eingabewert auf 1 gesetzt, dann setze Bit 2n auf 1 im Ausgabewert.<br />
2. Sind im Bitpaar (m, n), m&lt;n, beide Bits auf 1 gesetzt, dann setze Bit m+n+1 auf 1 im Ausgabewert.</p>
<p>Das sog. &#8220;Setzen des Bits auf 1&#8243; impliziert einen möglichen Übertrag: Ist das Bit bereits auf 1 gesetzt, so wird es auf 0 und das nachfolgende Bit auf 1 gesetzt.</p>
<p>Mit all den Sachen kann man schließlich den Algorithmus zur Berechnung von e als Pseudocode wie folgt beschreiben:<br />
<code><br />
void euler(int n)<br />
{<br />
&nbsp;&nbsp;Binary input;<br />
&nbsp;&nbsp;Binary output = 0;</p>
<p>&nbsp;&nbsp;output[0] = 1;<br />
&nbsp;&nbsp;output[n] = 1;</p>
<p>&nbsp;&nbsp;for (int q = 0; q < n; ++q) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;input = output;<br />
&nbsp;&nbsp;&nbsp;&nbsp;output = 0;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;for (int i = 0; i < input.length; ++i) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (input[i]) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output.setBit(2 * i);</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (j = i + 1; j < input.length; ++j) {<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (input[j])<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;output.setBit(i + j + 1);<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;&nbsp;&nbsp;}<br />
&nbsp;&nbsp;}<br />
}<br />
</code></p>
<p>Tja, und das war's dann auch schon. Mehr als simple Arithmetik ist nicht nötig, um e zu berechnen.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinkmeta.de/2010/02/eulersche-zahl-e-einfach-unendlich-genau-berechnen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>&#8220;vbr-new&#8221; noch schneller</title>
		<link>http://blog.thinkmeta.de/2009/10/vbr-new-noch-schneller/</link>
		<comments>http://blog.thinkmeta.de/2009/10/vbr-new-noch-schneller/#comments</comments>
		<pubDate>Sun, 25 Oct 2009 20:37:00 +0000</pubDate>
		<dc:creator>gk</dc:creator>
				<category><![CDATA[Fiber Pool]]></category>
		<category><![CDATA[Multicore MP3 Encoder]]></category>

		<guid isPermaLink="false">http://blog.thinkmeta.de/?p=160</guid>
		<description><![CDATA[<p>In Version 1.0.0.16 habe ich in &#8220;fpmp3enc&#8221; den &#8220;vbr-new&#8221;-Algorithmus nochmals verbessert:</p>
<p>Obwohl die Quantisierungs-Task mit hoher Priorität in den Fiber Pool hinzugefügt wurde, wurden sie und ihre Sub-Tasks in der alten Version erst dann ausgeführt, wenn andere Tasks mit ihrer Arbeit fertig waren.</p>
<p>Durch dieses Verhalten erreichten die Threads des Schedulers schnell die &#8220;Stop and Go&#8221;-Phase, in der [...]]]></description>
			<content:encoded><![CDATA[<p>In Version 1.0.0.16 habe ich in &#8220;fpmp3enc&#8221; den &#8220;vbr-new&#8221;-Algorithmus nochmals verbessert:</p>
<p>Obwohl die Quantisierungs-Task mit hoher Priorität in den Fiber Pool hinzugefügt wurde, wurden sie und ihre Sub-Tasks in der alten Version erst dann ausgeführt, wenn andere Tasks mit ihrer Arbeit fertig waren.</p>
<p>Durch dieses Verhalten erreichten die Threads des Schedulers schnell die &#8220;Stop and Go&#8221;-Phase, in der sie in sehr kurzen Abständen gestartet und gestoppt werden, was zu großen Performanceeinbußen führte. (Deswegen ist die Performance mit 4 Threads auch niedriger als mit 3.)</p>
<p>In der neuen Version kommunizieren nun die normal priorisierten Tasks mit dem Fiber Pool, um zu prüfen, ob Tasks mit hoher Priorität gestartet werden können. Wenn dem so ist, unterbrechen sie ihre Arbeit für das Ausführen der höher priorisierten Tasks.</p>
<p>Die &#8220;Stop and Go&#8221;-Phase wird auch hier erreicht, jedoch später, weil durch die neue Lastbalancierung die Threads effizienter genutzt werden können. Mehr als 3 Threads zu verwenden, wird aber weiterhin nicht empfohlen.</p>
<p>Die letzte Version hatte bereits einen Speedup von 2,14. Mit den durchgeführten Änderungen wird jetzt ein Speedup von <b>2,74</b> erreicht.</p>
<p>Mehr ist erstmal nicht drin&#8230; <img src='http://blog.thinkmeta.de/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinkmeta.de/2009/10/vbr-new-noch-schneller/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Streaming Framework in Arbeit</title>
		<link>http://blog.thinkmeta.de/2009/10/streaming-framework-in-arbeit/</link>
		<comments>http://blog.thinkmeta.de/2009/10/streaming-framework-in-arbeit/#comments</comments>
		<pubDate>Tue, 13 Oct 2009 17:16:15 +0000</pubDate>
		<dc:creator>gk</dc:creator>
				<category><![CDATA[Fiber Pool]]></category>
		<category><![CDATA[Streaming Framework]]></category>

		<guid isPermaLink="false">http://blog.thinkmeta.de/?p=154</guid>
		<description><![CDATA[<p>Nach der Fertigstellung von &#8216;fpMP3Enc&#8217; arbeite ich zur Zeit an einer generellen Streaming-Lösung namens &#8216;fpStream&#8217;. Ein Release dazu ist in den nächsten Wochen zwar noch nicht zu erwarten, weil ich noch den (Original-)Theora-Encoder integrieren möchte, dafür aber aktuell keine Zeit habe, weil ich noch an einem Artikel über asynchrone Programmierung brüte&#8230;</p>
<p>Ich kann aber schon soviel sagen, [...]]]></description>
			<content:encoded><![CDATA[<p>Nach der Fertigstellung von &#8216;fpMP3Enc&#8217; arbeite ich zur Zeit an einer generellen Streaming-Lösung namens &#8216;fpStream&#8217;. Ein Release dazu ist in den nächsten Wochen zwar noch nicht zu erwarten, weil ich noch den (Original-)Theora-Encoder integrieren möchte, dafür aber aktuell keine Zeit habe, weil ich noch an einem Artikel über asynchrone Programmierung brüte&#8230;</p>
<p>Ich kann aber schon soviel sagen, dass &#8216;fpStream&#8217; ähnlich modular und erweiterbar wie DirectShow ist, nur dass Prozessor-, Datei- und Speichermanagement zentral von &#8220;Fiber Pool&#8221; verwaltet wird.</p>
<p>Bereits implementiert sind folgende Module:<br />
- File Reader<br />
- File Writer<br />
- Console Writer<br />
- MD5 sum<br />
- WAV File Reader<br />
- MP3 File Writer<br />
- fpMP3Enc MP3 Encoder<br />
- Original Vorbis Encoder<br />
- Y4M File Reader<br />
- Original Theora Encoder (in Arbeit)</p>
<p>Wie bei DirectShow kann man einen Graph aus den einzelnen Modulen bauen, und zwar (etwas umständlich) über die Kommandozeile, z.B.:<br />
<code><br />
FPSTREAM readwavfile wav -f file.wav<br />
       + fpmp3enc mp3enc_1 -s wav --vbr-new<br />
       + fpmp3enc mp3enc_2 -s wav --cbr<br />
       + writemp3file mp3_1 -s mp3enc_1 -f vbrfile.mp3<br />
       + writemp3file mp3_2 -s mp3enc_2 -f cbrfile.mp3<br />
</code></p>
<p>Jedes Modul erhält einen Bezeichner (z.B. &#8220;wav&#8221;), der von anderen Modulen zum Verbinden über die Option &#8220;-s&#8221; verwendet wird. Das obige Beispiel erzeugt in einem Durchgang aus einer WAV-Datei zwei MP3-Dateien mit unterschiedlicher Kompression.</p>
<p>Wie gesagt, sobald Original-Theora integriert ist, gibt&#8217;s ein erstes Release dazu. Danach werde ich versuchen, eine multicore-fähige Version des Theora-Encoders zu implementieren.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinkmeta.de/2009/10/streaming-framework-in-arbeit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multicore-MP3-Encoder: Entwicklung abgeschlossen</title>
		<link>http://blog.thinkmeta.de/2009/10/multicore-mp3-encoder-entwicklung-abgeschlossen/</link>
		<comments>http://blog.thinkmeta.de/2009/10/multicore-mp3-encoder-entwicklung-abgeschlossen/#comments</comments>
		<pubDate>Fri, 02 Oct 2009 10:53:21 +0000</pubDate>
		<dc:creator>gk</dc:creator>
				<category><![CDATA[Fiber Pool]]></category>
		<category><![CDATA[Multicore MP3 Encoder]]></category>

		<guid isPermaLink="false">http://blog.thinkmeta.de/?p=150</guid>
		<description><![CDATA[<p>Gute Nachrichten: Die Entwicklung des MP3-Encoders ist abgeschlossen.</p>
<p>Details, Infos und Benchmarks findet Ihr auf der neuen Website.</p>
<p>Viel [...]]]></description>
			<content:encoded><![CDATA[<p>Gute Nachrichten: Die Entwicklung des MP3-Encoders ist abgeschlossen.</p>
<p>Details, Infos und Benchmarks findet Ihr auf der neuen <a href="http://www.thinkmeta.de">Website</a>.</p>
<p>Viel Spaß damit!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinkmeta.de/2009/10/multicore-mp3-encoder-entwicklung-abgeschlossen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multicore-MP3-Encoder: MDCT im asynchronen Fluss</title>
		<link>http://blog.thinkmeta.de/2009/08/multicore-mp3-encoder-mdct-im-asynchronen-fluss/</link>
		<comments>http://blog.thinkmeta.de/2009/08/multicore-mp3-encoder-mdct-im-asynchronen-fluss/#comments</comments>
		<pubDate>Fri, 21 Aug 2009 14:14:49 +0000</pubDate>
		<dc:creator>gk</dc:creator>
				<category><![CDATA[Fiber Pool]]></category>
		<category><![CDATA[Multicore MP3 Encoder]]></category>

		<guid isPermaLink="false">http://blog.thinkmeta.de/?p=131</guid>
		<description><![CDATA[<p>Die Entwicklung des Encoders schreitet leider nicht so schnell voran, jedoch sind kleine Fortschritte erkennbar.</p>
<p>In der aktuellen Version, die an bekannter Stelle zum Download bereitsteht, wird nun die MDCT-Phase asynchron ausgeführt.</p>
<p>Da MDCT im Vergleich zu den anderen Phasen relativ schnell berechnet wird, ist der Performancegewinn nicht besonders hoch. Auf meinem System lag er bei etwa 8%.</p>
<p>Die [...]]]></description>
			<content:encoded><![CDATA[<p>Die Entwicklung des Encoders schreitet leider nicht so schnell voran, jedoch sind kleine Fortschritte erkennbar.</p>
<p>In der aktuellen Version, die an <a href="http://www.fiberpool.de/de/downloads.html">bekannter Stelle</a> zum Download bereitsteht, wird nun die MDCT-Phase asynchron ausgeführt.</p>
<p>Da MDCT im Vergleich zu den anderen Phasen relativ schnell berechnet wird, ist der Performancegewinn nicht besonders hoch. Auf meinem System lag er bei etwa 8%.</p>
<p>Die Portierung des seriellen in asynchronen Code habe ich in mehreren Schritten durchgeführt, die ich hier näher beschreiben möchte:</p>
<p><b>Ursprünglicher Zustand:</b><br />
Die folgende Abbildung zeigt die MDCT-Phase beim Ausführen des seriellen Codes:</p>
<p align="center"><img src="http://blog.thinkmeta.de/wp-content/uploads/2009/08/mdct1.png" alt="MDCT 1" title="MDCT 1" width="346" height="74" class="aligncenter size-full wp-image-132" /></p>
<p>Aus den eingehenden Samples wird zunächst das psychoakustische Modell (PSY) berechnet, bevor darauf MDCT angewandt wird. Nach der MDCT wird der Quantisierer ausgeführt.</p>
<p>Die Abhängigkeiten sind wie folgt: Die MDCT ist abhängig von PSY, weil dort die Block Types (long/short) berechnet werden. Der Quantisierer ist abhängig von dem Ergebnis der MDCT.</p>
<p><b>Schritt 1: Erzeugen einer MDCT-Task</b><br />
Für eine gute Basis zur MDCT-Parallelisierung werden nun alle Aktivitäten, die mit MDCT zu tun haben, in eine Task ausgegliedert:</p>
<p align="center"><img src="http://blog.thinkmeta.de/wp-content/uploads/2009/08/mdct2.png" alt="MDCT 2" title="MDCT 2" width="450" height="251" class="aligncenter size-full wp-image-133" /></p>
<p>Die wichtigste Änderung gegenüber dem ursprünglichen Zustand ist, dass die Task nun den MDCT-Zustand selbst (Subband-Samples) verwaltet und er nicht mehr in der globalen Datenstruktur gespeichert wird.</p>
<p>Obwohl es sich noch um eine parallel ausgeführte Task handelt, wird sie durch die eingesetzten Synchronisationsprimitiven seriell ausgeführt.</p>
<p><b>Schritt 2: Überlappende Berechnung der Subbänder</b><br />
In der vorherigen Abbildung wurde schon angedeutet, dass die Berechnung der Subband-Samples nicht von PSY, sondern nur von den eingehenden Samples abhängig ist. Daher wird die MDCT-Task nun zusätzlich mit ihnen synchronisiert:</p>
<p align="center"><img src="http://blog.thinkmeta.de/wp-content/uploads/2009/08/mdct3.png" alt="MDCT 3" title="MDCT 3" width="450" height="251" class="aligncenter size-full wp-image-134" /></p>
<p>Die Subband-Samples eines Frames können nun parallel zum PSY berechnet werden.</p>
<p><b>Schritt 3: Überlappen mit dem Quantisierer</b><br />
Die MDCT berechnet für ein Frame insgesamt vier xr-Arrays, jeweils zwei für jeden Kanal. Da der Quantisierer zu seiner Ausführung nicht sofort alle vier Arrays benötigt, kann er bereits nach der Berechnung des ersten Arrays gestartet werden. Die restlichen drei werden überlappend berechnet:</p>
<p align="center"><img src="http://blog.thinkmeta.de/wp-content/uploads/2009/08/mdct4.png" alt="MDCT 4" title="MDCT 4" width="450" height="251" class="aligncenter size-full wp-image-135" /></p>
<p><b>Schritt 4: Parallele Ausführung der MDCT</b><br />
Die MDCT kann für jeden Kanal unabhängig voneinander ausgeführt werden. Dafür wird die Task in zwei Sub-Tasks aufgeteilt:</p>
<p align="center"><img src="http://blog.thinkmeta.de/wp-content/uploads/2009/08/mdct5.png" alt="MDCT 5" title="MDCT 5" width="450" height="251" class="aligncenter size-full wp-image-136" /></p>
<p><b>Schritt 5: Weitere Überlappungen mit PSY</b><br />
Die Block Types werden in PSY in zwei Phasen berechnet. Bereits nach der ersten Phase können die ersten beiden xr-Arrays berechnet werden:</p>
<p align="center"><img src="http://blog.thinkmeta.de/wp-content/uploads/2009/08/mdct6.png" alt="MDCT 6" title="MDCT 6" width="450" height="251" class="aligncenter size-full wp-image-137" /></p>
<p><b>Schritt 6: Entfernen der MDCT-Container-Task</b><br />
Durch die Aufteilung der MDCT in zwei Sub-Tasks hat die eigentliche Task keine sinnvolle Aufgabe mehr. Sie wird entfernt und die bisherigen Sub-Tasks greifen nun direkt auf die Samples und die Block Types zu:</p>
<p align="center"><img src="http://blog.thinkmeta.de/wp-content/uploads/2009/08/mdct7.png" alt="MDCT 7" title="MDCT 7" width="450" height="377" class="aligncenter size-full wp-image-138" /></p>
<p><b>Der nächste Schritt</b><br />
Die aktuelle Version implementiert Schritt 6, es geht aber noch besser: Die Berechnung der Subband-Samples kann in eine separate Task übertragen werden, in der schon Samples für die kommenden Frames berechnet werden können. Das werde ich als Nächstes in Angriff nehmen.</p>
<p>Welche Phase (PSY oder Quantisierer) ich danach parallelisieren werde, weiss ich aktuell noch nicht. Eins kann ich aber schon vorweg sagen, dass auf ähnliche Weise wie hier bei der MDCT einiges herauszuholen ist!</p>
<p>Bis bald!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinkmeta.de/2009/08/multicore-mp3-encoder-mdct-im-asynchronen-fluss/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Multicore-MP3-Encoder: Zwischenversion released</title>
		<link>http://blog.thinkmeta.de/2009/07/multicore-mp3-encoder-zwischenversion-released/</link>
		<comments>http://blog.thinkmeta.de/2009/07/multicore-mp3-encoder-zwischenversion-released/#comments</comments>
		<pubDate>Fri, 24 Jul 2009 22:15:33 +0000</pubDate>
		<dc:creator>gk</dc:creator>
				<category><![CDATA[Fiber Pool]]></category>
		<category><![CDATA[Multicore MP3 Encoder]]></category>

		<guid isPermaLink="false">http://blog.thinkmeta.de/?p=124</guid>
		<description><![CDATA[<p>Wie angekündigt gibt es ab sofort die neue Version des MP3-Encoders zum Download.</p>
<p>Die Queues wurden durch SequentialVirtualMemoryPipe-Objekte ersetzt. Dadurch wurde die Kommunikation zwischen den Tasks deutlich reduziert. Folgende Abbildung zeigt den aktuellen Datenfluss:</p>
<p align="center"></p>
<p>Beim Ausführen meines Tests bin ich auf folgende Ergebnisse gekommen:</p>
<p>Dateien einzeln encoden: 23,8x
Dateien parallel encoden: 89,2x</p>
<p>[Nachtrag:] Dies entspricht einem Speedup von 3,75. LAME [...]]]></description>
			<content:encoded><![CDATA[<p>Wie angekündigt gibt es ab sofort die neue Version des MP3-Encoders zum <a href="http://www.fiberpool.de/de/downloads.html">Download</a>.</p>
<p>Die Queues wurden durch SequentialVirtualMemoryPipe-Objekte ersetzt. Dadurch wurde die Kommunikation zwischen den Tasks deutlich reduziert. Folgende Abbildung zeigt den aktuellen Datenfluss:</p>
<p align="center"><img src="http://blog.thinkmeta.de/wp-content/uploads/2009/07/mp3_1.5.png" alt="Zwischenversion 1.5" title="Zwischenversion 1.5" width="400" height="62" class="aligncenter size-full wp-image-127" /></p>
<p>Beim Ausführen meines Tests bin ich auf folgende Ergebnisse gekommen:</p>
<p>Dateien einzeln encoden: 23,8x<br />
Dateien parallel encoden: 89,2x</p>
<p><b>[Nachtrag:]</b> Dies entspricht einem Speedup von 3,75. LAME dazu im Vergleich: einzeln 24,6x, parallel 48,5 &#8211; Speedup etwa 2.</p>
<p>Mit ein paar Tricks lässt sich der letzte Wert vielleicht noch über die 90er-, vielleicht bis zur 100er-Marke steigern, dann ist aber das Maximale für meinen Prozessor erreicht.</p>
<p>Ausgehend von meinem ersten Testwert von 22,3x wird mit 89,2x lineare Skalierung erreicht. Bedenkt man, dass beim ersten Test bereits mehrere Threads zum Einsatz kamen, skaliert der Encoder sogar super linear beim Konvertieren von mehreren Dateien.<br />
Diese Eigenschaft wird durch die <a href="http://blog.thinkmeta.de/2009/03/parallele-dateiverarbeitung/">parallele Dateiverarbeitung</a> erzielt: Je mehr Dateien zu konvertieren sind, umso weniger fällt das I/O ins Gewicht, weil bereits während der Konvertierung einer Datei schon die nächsten Dateien in den Speicher geladen werden.</p>
<p>Viel Spaß damit!</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.thinkmeta.de/2009/07/multicore-mp3-encoder-zwischenversion-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
