Sziasztok!
Az alabbi pici fugvenyt kene mmx hasznalataval assemblybe megirnom (iskolai feladat, es egy ideje szenvedek vele, de sehogy nem megy).
void Filter(unsigned char * buf, int width,int height,char bpp) {
int i,j,tmp;
for (i=0;i<height*bpp;i++) { // wirsze
for (j=0;j<width;j++) { // kolumny
tmp=buf[i*width+j];
buf[i*width+j]=(unsigned char)(~(tmp));
}
}
}
a legnagyobb problemam mar a kezdet kezdetenel a negalasnal jelentkezik, mivel elvileg nincs ilyen utasitas az mmx utasitas keszletben.
Koszi
- 5218 megtekintés
Hozzászólások
hat akkor pxor-oljal 0xffffffffffffffff-fel.
- Use the Source Luke ! -
- A hozzászóláshoz be kell jelentkezni
thx
- A hozzászóláshoz be kell jelentkezni
Szerintem nem kellene minden egyes utasitasnak MMX utasitasnak lennie.
- A hozzászóláshoz be kell jelentkezni
en ugy gondoltam, hogy elvileg abbol a buffbol bekapolom a cuccot az mm0 registrerbe negalom es kes isz a kimenet
csak ez nem olyan egyszeruen akar megoldodni.
- A hozzászóláshoz be kell jelentkezni
mm1: 0xffffffffffffffff
esi: buff
ecx: width*height*bpp
edx: 0
majd valami ilyesmi (felteve, hogy ecx oszthato 8-al)
loop:
leal (%esi,%edx), %eax
movq (%eax), %mm0
pxor %mm0, %mm1
movq %mm0, (%eax)
addl $8, %edx
cmpl %edx, %ecx
jg loop
- A hozzászóláshoz be kell jelentkezni
tobb sebbol verzik a megoldas, mint pl. hogy nem kell se
a leal se a ket movq, azonkivul ertelmesebb kezdoertekekkel (pl. hogy
a sor vegerol kezded a feldolgozast) a cmp-t is lehet eliminalni.
amugy sem ertem miert kene megirni mas hazi feladatat.
- Use the Source Luke ! -
- A hozzászóláshoz be kell jelentkezni
Egy egyszeru es konnyen ertheto oktatasi peldarol van szo. Biztos lehet sokkal hatekonyabb kodot is irni,
de az sokkal kevesbe ertheto. Pl. loop unrolling-gal jol ossze lehet zavarni a tanulot.
- A hozzászóláshoz be kell jelentkezni
jo duma, egy a gond az altalam javasolt kod amellett, hogy 3-szor gyorsabb, ugyanolyan ertheto. loop unrolling itt amugy nem kerult szoba, csak legfeljebb a proci alapveto cimzesmodjai.
- Use the Source Luke ! -
- A hozzászóláshoz be kell jelentkezni
lemerted? :-)
movq: a CPU load/modify/store uzemmodban mukodik, csak ezt tudja. 'pxor mem, reg' utasitas szerintem nincs, csak 'pxor reg, mem' (implicit load-dal) es az eredmeny mindig a reg-ben keletkezik. Azt valahogy vissza kell juttatni a memoriaba :-).
- A hozzászóláshoz be kell jelentkezni
ah, valoban. akkor movq-k kellenek, de lea meg a cmp nem. igazabol a lea akasztott ki, mert annak tenyleg nem latom ertelmet ott.
- Use the Source Luke ! -
- A hozzászóláshoz be kell jelentkezni
igen oktatasi pelda, eled raktak, hogy tessek old meg, fv-t mar irtal assemblyben (igen csak az egy picit egyszerubb volt, de azzal is kellett szenvedni) aztan emg azt mondja ott van intel utasitaslapja pdfben ird at ezt a fv-t a programbol aassemblyben mmx hasznalosra, vagy legalabb : buf[i*width+j]=(unsigned char)(~(tmp));
Ha mondom koszi, talan vmit magyarazni, vayg valami hogy megis hogyan, de semmi, orat vegig google, hogy legalabb valahonnan elinduljak, aztan itthon is google, de az istenert meg elindulni sem tudok semerre.
Szoval vegso ketsegbe esesemben fordultam hozzatok, bar tudom hogy baromira nem nektek kell megoldani a hazi feladatomat. Csakhat ehhez egesz egyszeruen hulye vagyok, de sakjnos meg kell csinalni.
- A hozzászóláshoz be kell jelentkezni
Vagy osszezavarja a tanart :)
Anno nekunk vizsgan kellett egy faktorialis szamolot irni assemblyben. Allitolag (en nem jartam be orara:)) evkozben a tanar felirt valami kb 20 soros megoldast, es gondolom azt varta, hogy azt majd bemagolja mindenki.
Na most vizsgan en megirtam ennyibol:
mov eax,1
mov ecx,N
x: imul eax,ecx
loop x
mov N,eax
a tanar ravagta hogy ez nem jo. mondom, de jo. de nem. de de. na probaljuk ki. kiprobaltuk, mukodik. masik ertekkel is. harmadikkal is. de a tanar szerint ez akkor sem jo, mert o nem ezt tanitotta. aztan elmagyaraztam neki lepesrol lepesre hogy mukodik, vegul elfogadta nagy nehezen.
szoval ovatosan az optimalizalassal, mert meg a vegen tul jol sikerul :)
A'rpi
- A hozzászóláshoz be kell jelentkezni
igen az ilyen tanarokat en is nagyon szeretm. Viszont az en megoldasom meg mindig nem mukodik, mostmar odaig fajultam hogy fogtam magam, es atirtam egy picit a gcc altal generalt kodot, csak ez nem tudom hogy igy mennyire mmx kihasznalasa. Raneznetek:
.globl Filter
.type Filter, @function
Filter:
pushl %ebp
movl %esp, %ebp
subl $20, %esp
movl 20(%ebp), %eax
movb %al, -20(%ebp)
movl $0, -4(%ebp)
.L3:
movl $0, -8(%ebp)
movl -8(%ebp), %eax
.L5:
movl -4(%ebp), %eax
imull 12(%ebp), %eax
addl -8(%ebp), %eax
addl 8(%ebp), %eax
movzbl (%eax), %eax
movzbl %al, %eax
movl %eax, -12(%ebp)
movl -4(%ebp), %eax
imull 12(%ebp), %eax
addl -8(%ebp), %eax
movl %eax, %edx
addl 8(%ebp), %edx
movq -12(%ebp), %mm0 #innen mmx
movl $0xffffffff, %esi
movd %esi, %mm1
pxor %mm1, %mm0
movd %mm0, %eax #idaig mmx
movb %al, (%edx)
addl $1, -8(%ebp)
movl -8(%ebp), %eax
cmpl 12(%ebp), %eax
jl .L5
addl $1, -4(%ebp)
movsbl -20(%ebp),%eax
imull 16(%ebp), %eax
cmpl -4(%ebp), %eax
jg .L3
leave
ret
- A hozzászóláshoz be kell jelentkezni
Mennyivel gyorsabb ez így, mint a fordító által generált kód?
- A hozzászóláshoz be kell jelentkezni
nem mukodik szegmens hiba, de meg probalkozom
- A hozzászóláshoz be kell jelentkezni
Az is kell, hogy buff 8 byte-os alignment-tel rendelkezzen (magyarul a cim oszthato 8-cal). Ellenkezo esetben johet a szegmens hiba.
- A hozzászóláshoz be kell jelentkezni
a szegmens hiba itt jelentkezik: movq 0xffffffffffffffff, %mm1
es nem tudom sajnos hogy miert, ha kikommentezem,s zepen lefut, csak nem csinal semmit mert 0-val xorrol
- A hozzászóláshoz be kell jelentkezni
ismet a segitsegetek szeretnem kerni, jelnleg itt jarok:
.section .text
.globl Filter
.type Filter, @function
Filter:
pushl %ebp
movl %esp, %ebp
imull %ecx, %ebx
movl 16(%ebp), %ecx
imull %ebx, %ecx #width*height*bpp
movl $0xffffffff, %esi
movd %esi, %mm1
loop:
movq (%eax), %mm0
pxor %mm1, %mm0
movq %mm0, (%eax)
addl $8, %edx
cmpl %edx, %ecx
jg loop
movl %ebp, %esp
popl %ebp
ret
igy lefordul, de azonkivul h kiirja h lefotutott nem csinal semmit.
- A hozzászóláshoz be kell jelentkezni
es termeszetesen itt van a hozzatartozo kod is, amiben a fv szerepel:
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "SDL.h"
#include "SDL_image.h"
SDL_Surface* Load_image(char *file_name)
{
SDL_Surface* tmp = IMG_Load(file_name);
if ( tmp == NULL ) {
fprintf(stderr, "Couldn't load %s: %s\n",
file_name, SDL_GetError());
exit(0);
}
return tmp;
}
void Paint(SDL_Surface* image, SDL_Surface* screen)
{
SDL_BlitSurface(image, NULL, screen, NULL);
SDL_UpdateRect(screen, 0, 0, 0, 0);
};
void Filter(unsigned char * buf, int width,int height,char bpp);
int main(int argc, char *argv[])
{
Uint32 flags;
SDL_Surface *screen, *image;
int depth, done;
SDL_Event event;
/* Initialize the SDL library */
if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) {
fprintf(stderr, "Couldn't initialize SDL: %s\n",SDL_GetError());
return(255);
}
flags = SDL_SWSURFACE;
image = Load_image( "2.bmp" );
printf( "\n\nImage properts:\n" );
printf( "BitsPerPixel = %i \n", image->format->BitsPerPixel );
printf( "BytesPerPixel = %i \n", image->format->BytesPerPixel );
printf( "width %d ,height %d \n\n", image->w, image->h );
SDL_WM_SetCaption(argv[1], "showimage");
/* Create a display for the image */
depth = SDL_VideoModeOK(image->w, image->h, 32, flags);
if ( depth == 0 ) {
if ( image->format->BytesPerPixel > 1 ) {
depth = 32;
} else {
depth = 8;
}
} else
if ( (image->format->BytesPerPixel > 1) && (depth == 8) ) {
depth = 32;
}
if(depth == 8)
flags |= SDL_HWPALETTE;
screen = SDL_SetVideoMode(image->w, image->h, depth, flags);
if ( screen == NULL ) {
fprintf(stderr,"Couldn't set %dx%dx%d video mode: %s\n",
image->w, image->h, depth, SDL_GetError());
}
/* Set the palette, if one exists */
if ( image->format->palette ) {
SDL_SetColors(screen, image->format->palette->colors,
0, image->format->palette->ncolors);
}
/* Display the image */
Paint(image, screen);
done = 0;
while ( ! done ) {
if ( SDL_PollEvent(&event) ) {
switch (event.type) {
case SDL_KEYUP:
switch (event.key.keysym.sym) {
case SDLK_ESCAPE:
case SDLK_TAB:
case SDLK_q:
done = 1;
break;
case SDLK_SPACE:
case SDLK_f:
SDL_LockSurface(image);
printf("Start filtering... ");
Filter(image->pixels,image->w,image->h, image->format->BytesPerPixel );
printf("Done.\n");
SDL_UnlockSurface(image);
printf("Repainting after filtered... ");
Paint(image, screen);
printf("Done.\n");
break;
case SDLK_r:
printf("Reloading image... ");
image = Load_image( argv[1] );
Paint(image,screen);
printf("Done.\n");
break;
case SDLK_PAGEDOWN:
case SDLK_DOWN:
case SDLK_KP_MINUS:
printf("Aktual size is:\n");
break;
case SDLK_PAGEUP:
case SDLK_UP:
case SDLK_KP_PLUS:
printf("Aktual size is:");
break;
case SDLK_s:
printf("Saving surface at nowy.bmp ...");
SDL_SaveBMP(image, "nowy.bmp" );
printf("Done.\n");
default:
break;
}
break;
case SDL_QUIT:
done = 1;
break;
default:
break;
}
} else {
SDL_Delay(10);
}
}
SDL_FreeSurface(image);
SDL_Quit();
return(0);
}
- A hozzászóláshoz be kell jelentkezni
Figyelj. Ha valami egyszerut akarsz tesztelni, ne irj bonyolult tesztprogit hozza. Csinajl egy alap c fajlt, amibe se sdl, se semmi nincs, csak generalsz a bufba valami fals ertekeket, es a vegen kiirod a kimenetet. Ne erdekeljen, hogy a buf micsoda, a w a h micsoda, semmi, csak a szamolas. Ha ugy mukodik, akkor elkepzelheto, hogy a SDL-es programban is mukodni fog. De azt felejtsd el, hogy rogton elesben tesztelsz egy olyan modult, amirol azt sem tudod, mukodik-e.
- A hozzászóláshoz be kell jelentkezni
ez igy igaz amit leirtal, azt szamolja egyebkent amit kene, csak nem adja vissza valamiert. de vegul maradok a gcc altal generalt atirtnal, szerintem vegulis az is jo csak egy kicsit hosszabb, ha sikerult megfejtenem a pontos mukodeset jo lesz nekem az is.
- A hozzászóláshoz be kell jelentkezni