LabVIEWForum.de
"Datenring" in dll verarbeiten - Druckversion

+- LabVIEWForum.de (https://www.labviewforum.de)
+-- Forum: LabVIEW (/Forum-LabVIEW)
+--- Forum: LabVIEW Allgemein (/Forum-LabVIEW-Allgemein)
+---- Forum: DLL & externer Code (/Forum-DLL-externer-Code)
+---- Thema: "Datenring" in dll verarbeiten (/Thread-Datenring-in-dll-verarbeiten)



"Datenring" in dll verarbeiten - grey - 07.12.2009 14:28

Hallo,

ich versuche gerade eine .dll zu schreiben die dynamisch ein 2D Array aufsummieren soll, also sozusagen eine "moving" Summenbildung durchführt.
Bei der Rechnung stellte ich mir an sich vor, eine Art Ring anzulegen und am Ende jeweils immer nur das neue Bild aufzuaddieren und das, welches am Anfang des Ringes stand zu subtrahieren.

Gerade habe ich jedoch den Eindruck, dass das Programm nur jeweis ein Bild mehrfach aufsummiert und dann gleiches mit dem Nächsten macht. Also P1+P1+P1...+P1 rechnet, statt P1+P2+P3+...Pn.
Das würde darauf schließen lassen, dass die .dll immer wieder von neuem aufgerufen wird und man somit nur jeweils Berechnungen an einem Bild mit einer .dll durchführen könnte. Das das aber wenig schön ist und sicherlich auch komplexere Dinge gehen müssen, würde ich gerne wissen wie ich das vorliegende Problem lösen kann?

Unten angefügt ist der entsprechende C code für die .dll.



<div class='codetop'>CODE</div><div class='codemain' style='height:200px;white-space:pre;overflow:auto'>/* Call Library source file */

#include "extcode.h"
#include <stdio.h>
#include <stdlib.h>

/* Typedefs */

typedef struct {
int32_t dimSizes[2];
uint8_t elt[1];
} TD1;
typedef TD1 **TD1Hdl;

typedef struct {
int32_t dimSizes[2];
uint32_t elt[1];
} TD2;
typedef TD2 **TD2Hdl;


//Definitios of the Subprograms
int* callocvector(int);
int* freevector(int*);


__declspec(dllexport) int32_t MovingSum(TD1Hdl NewPicture, TD2Hdl SumPic, int32_t *AverageLength);

int32_t MovingSum(TD1Hdl NewPicture, TD2Hdl SumPic, int32_t *AverageLength)
{
int i, k, numrow, numcol, *PicArray, L, picLength, AvPicNum;

numrow=(*NewPicture)->dimSizes[0];
numcol=(*NewPicture)->dimSizes[1];

picLength=numrow*numcol;
L=picLength* *AverageLength;
PicArray= callocvector(L);


for ( k=0;k<*AverageLength;k++)
{
AvPicNum=k*picLength;
for ( i=0;i<picLength;i++)
{
(*SumPic)->elt[i]=(*SumPic)->elt[i]+(*NewPicture)->elt[i]-PicArray[AvPicNum+i];
PicArray[AvPicNum+i]=(*NewPicture)->elt[i]+1;
}
}

PicArray=freevector(PicArray);

return 0;
}


//Unterprogramme zur dynamischen Speicherallokation

/*--------------------------------------------
"callocvector" allocates the memory for a
dynamic vector of length n and initializes it
--------------------------------------------*/

int* callocvector(int n)
{
int j;
int* vector = calloc(n,sizeof(int));

for (j=0; j<n; j++)
{
vector[j] = 0;
}
return(vector);
}


/*--------------------------------------------
"freevector" dis-allocates the memory of
a dynamic vector of arbitrary length and
sets the pointer to NULL
--------------------------------------------*/

int* freevector(int* vector)
{
free(vector);
return(NULL);
}</div>


"Datenring" in dll verarbeiten - rolfk - 07.12.2009 15:18

Ich verstehe nur Bahn

Wo denkst Du denn die verschiedenen Bilder von einem Aufruf der Funktion zum nächsten abzuspeichern? Da müsste mindestens eine static Variable irgendwo sein oder noch besser die ganze History sollte jeweils als extra Parameter mitgegeben werden aber selbst damit ist Deine callocvector()/freevector() Implementation meiner Meinung nach alles ausser einer Ringbufferimplementation.


"Datenring" in dll verarbeiten - grey - 07.12.2009 15:47

Ja, genau da liegt das Problem.
Ich weiß gerade eben nicht wie ich den gewünschten Effekt möglichst elegant implementieren kann, da ich ja pro Aufruf auch wirklich nur das aktuelle Bild übergeben möchte, statt größere Datenmengen zwischen LV und der dll auszutauschen.
Mir ist gerade aber nicht klar, wie ich die Daten anders von einem Aufruf zum anderen gerettet bekommen könnte. Gibt es da keine Möglichkeit?

Wenn nicht muss ich es wohl wirklich so machen, dass ich jeweils ein großes Array aus den letzten X Bildern hineingebe, verarbeite, wieder ausgebe und über ein shift register wieder neu an den Eingang lege (das wäre jedenfalls nun meine erste Idee zu einer Alternative).


"Datenring" in dll verarbeiten - rolfk - 07.12.2009 16:09

' schrieb:Wenn nicht muss ich es wohl wirklich so machen, dass ich jeweils ein großes Array aus den letzten X Bildern hineingebe, verarbeite, wieder ausgebe und über ein shift register wieder neu an den Eingang lege (das wäre jedenfalls nun meine erste Idee zu einer Alternative).

Und wenn richtig getan keinerlei Performanceproblem.


"Datenring" in dll verarbeiten - grey - 07.12.2009 22:36

Das hätte ich dann allerdings doch erwartet, dass es etwas aufwendiger wird aber wenn es doch nicht so ist kann ich das ja machen.
Also als richtig getan würde ich folgende Schritte ansehen: Das Ganze als Pointer und nicht Array Handler übergeben und dessen Speicherplatz außerhalb der Schleife einmal zu allokieren.
Gibt es daneben sonst noch Sachen die man beachten muss, oder wie man die Performance noch steigern könnte?

Vielen Dank übrigens schon einmal für die raschen Antworten.


"Datenring" in dll verarbeiten - rolfk - 08.12.2009 07:58

' schrieb:Das hätte ich dann allerdings doch erwartet, dass es etwas aufwendiger wird aber wenn es doch nicht so ist kann ich das ja machen.
Also als richtig getan würde ich folgende Schritte ansehen: Das Ganze als Pointer und nicht Array Handler übergeben und dessen Speicherplatz außerhalb der Schleife einmal zu allokieren.
Gibt es daneben sonst noch Sachen die man beachten muss, oder wie man die Performance noch steigern könnte?

Vielen Dank übrigens schon einmal für die raschen Antworten.

Pointer oder Handle macht wenig Unterschied. Auf LabVIEW Ebene bleibt es im Prinzip einfach ein Wire mit dem nichts anderes getan wird als es vom Schieberegister in die Call Library Node und von da wieder zurück ins Schieberegister zu verbinden. Dabei dafür sorgen dass Du beide Seiten der Call Library Node wirest.

Das mit der Preallokation voor der Loop ist eine gute Idee und entsprechend natürlich Deallokation danach.


"Datenring" in dll verarbeiten - grey - 08.12.2009 08:06

Na, das ist ja dann sogar noch einfacher als ich dachte, das werde ich dann so machen.

Vielen Dank nochmal für deine Hilfe.