No ACL setup yet! Denying access to everyone.
en:edu:zmitac:s1:apl:lab:lab4

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
en:edu:zmitac:s1:apl:lab:lab4 [2024/12/05 12:14] – [The example code] ktokarzen:edu:zmitac:s1:apl:lab:lab4 [2024/12/05 12:39] (current) – [Tasks to be done during laboratory] ktokarz
Line 4: Line 4:
 ===== The aim of the exercise ===== ===== The aim of the exercise =====
 The aim of the exercise is to learn about vector instructions called SIMD (Single Instruction Multiple Data) and passing parameters to functions as references to common memory. The aim of the exercise is to learn about vector instructions called SIMD (Single Instruction Multiple Data) and passing parameters to functions as references to common memory.
-As in previous laboratories we'll write the dll library with functions called from C++ program. +As in previous laboratory exercises, we'll write the dll library with functions called from the C++ program. 
-Functions will calculate the sum, difference, multiplication and division of four single precision floating point values.+Functions will calculate the sum, difference, multiplication, and division of four single precision floating point values.
 <note>The configuration and solution creation process is identical to the one presented in exercise 2. The main program should be written in C++ and dynamically linked library in assembler.</note> <note>The configuration and solution creation process is identical to the one presented in exercise 2. The main program should be written in C++ and dynamically linked library in assembler.</note>
 ===== First example code ===== ===== First example code =====
 In the first example, we'll write the function in assembler with an internal definition of variables to show how to define floating point vectors in the assembly program. In the first example, we'll write the function in assembler with an internal definition of variables to show how to define floating point vectors in the assembly program.
-The following code is divided into three parts. The C++ part calls the function in a dynamically linked library. The function, called Sum_of_vectors(), written in the assembler file, calculates the sum of two vectors of four single precision floating point data. They are defined as first_vector and second_vector. The resulting value is stored in the resulting_vector variable. Third file is def file which exports function from assembler source to C++ program.+The following code is divided into three parts. The C++ part calls the function in a dynamically linked library. The function, called Sum_of_vectors(), written in the assembler file, calculates the sum of two vectors of four single precision floating point data. They are defined as first_vector and second_vector. The resulting value is stored in the resulting_vector variable. The third file is a def file which exports the function from the assembler source to the C++ program.
  
 C++ file C++ file
Line 24: Line 24:
     std::cout << "Hello World!\n";     std::cout << "Hello World!\n";
     dllHandle = LoadLibrary(TEXT("JaAsm.dll"));     dllHandle = LoadLibrary(TEXT("JaAsm.dll"));
-    std::cout << procedura(); 
- 
     MyProc Sum_of_vectors = (MyProc)GetProcAddress(dllHandle, "Sum_of_vectors");     MyProc Sum_of_vectors = (MyProc)GetProcAddress(dllHandle, "Sum_of_vectors");
 +    
 +    Sum_of_vectors();
 } }
 </code> </code>
Line 45: Line 45:
 ;   No input parameters, no result returned ;   No input parameters, no result returned
 ;**************************************************************************** ;****************************************************************************
-FindChar_1 PROC  
-    PUSH RSI 
-    LEA RSI, DataString      ; load the address of variable 'DataString' into reg. ESI  
-    MOV AL, 'J'              ; load the code of character 'J' into reg. AH  
-Check_End:  
-    CMP BYTE PTR [RSI], 0FFH ; is it the end of a string (special character FF)?  
-    JE Not_Find              ; found end character (guard)  
-    CMP AL, [RSI]            ; compare a character with chosen char of string 'DataString'  
-    JE Got_Equal             ; character found!  
-    ADD RSI, 1               ; increment an offset 
-    JMP Check_End            ; search loop  
-Got_Equal:  
-    MOV DL, [RSI]            ; load found char into DL  
-    JMP Done  
-Not_Find:  
-    MOV RAX,0                ; character not found  
-    POP RSI 
-    RET                      ; return from procedure  
-Done:  
-    MOV RAX,1                ; character found 
-    POP RSI 
-    RET                      ; return form procedure 
-FindChar_1 ENDP              ; end of FindChar_1  
  
-;**************************************************************************** +Sum_of_vectors PROC  
-;   Procedure to measure the time of other function execution +    PUSH RSI                              ; RSI is non-volatile register 
-;   No input parameters, result is the time (number of processor ticks) +    LEA RSI, first_vector                 ; this helps to find the address in the memory for dump 
-;****************************************************************************  +             
-ReadTime_1 PROC +    MOVUPS XMM0, OWORD PTR first_vector   ; load address of variable 'SourceDataString' into reg. RSI 
-    RDTSC                    ; read of time stamp counter +    MOVUPS XMM1, OWORD PTR second_vector  ; load address of variable 'DestinBaseString' into reg. RDI 
-    MOV RCX,RAX+    ADDPS  XMM0, XMM1 
 +    MOVUPS OWORD PTR resulting_vector, XMM0
  
-    CALL FindChar_1          ; call to the tested function +    POP RSI 
- +    RET           ; return form procedure 
-    RDTSC +Sum_of_vectors ENDP           ; end of CopyString_base    
-    SUB RAX,RCX +
- +
-    RET                      ; return form procedure +
-ReadTime_1 ENDP +
  
 END END
Line 130: Line 104:
     std::cout << "Result_3 " << (result_vector[2]) << std::endl;     std::cout << "Result_3 " << (result_vector[2]) << std::endl;
     std::cout << "Result_4 " << (result_vector[3]) << std::endl;     std::cout << "Result_4 " << (result_vector[3]) << std::endl;
- 
 } }
 </code> </code>
Line 138: Line 111:
 .code .code
  
-;****************************************************************************  +;**************************************************************************** 
-;   This function +;   Function to calculate the sum of two vectors 
 +;   Accepts two parameters, returns result by third parameter
 ;****************************************************************************  ;**************************************************************************** 
 Sum_of_vectors PROC  Sum_of_vectors PROC 
- 
     MOVUPS XMM0, OWORD PTR [RCX]   ; load content of memory pointed by the first parameter     MOVUPS XMM0, OWORD PTR [RCX]   ; load content of memory pointed by the first parameter
     MOVUPS XMM1, OWORD PTR [RDX]   ; load content of memory pointed by the second parameter     MOVUPS XMM1, OWORD PTR [RDX]   ; load content of memory pointed by the second parameter
Line 156: Line 129:
 </code> </code>
  
-Def file is the same as in previous exemple.+Def file is the same as in a previous example. 
 ===== Tasks to be done during laboratory ===== ===== Tasks to be done during laboratory =====
-  - Compile the example code and observe its behaviour. Set the breakpoint at the beginning of the code and see how the contents of the registers change with every loop pass.  +  - Compile the examples and observe their behaviour. Set the breakpoint at the beginning of the code and see how the contents of the registers change. Observe XMM registers as calculations are performed there. 
-  - Make the function more universal: define the string in a C++ file and pass its address as the parameter to the function. Pass the character as the second parameter. +  - Write additional functions to calculate subtraction, multiplication, and division of arguments. 
-  - Rewrite the search algorithm with vector instructions (SSE, or AVX). Suggest what to do if the string length is not a multiple of register size. +  - Write the program which calculates the average of the values in the table using vector (SIMD) instructions. Program assumptions: 
-  - Compare execution time for scalar (normal) instructions and vector instruction for the same string.+  * Table contains 64 float values and is defined in C++ file. 
 +  * And address of the table is passed to the function as the first argument. 
 +  * A size of the table is passed as a second argument (you can assume that the size of the table is a multiply of 4). 
 +  * Function uses SIMD instructions. 
 +  * Function returns the value as the scalar, traditionally by XMM0. 
 + 
 +=====For the report===== 
 +  - Include the code of additional functions. 
 +  - Include the code of the average program (both C++ and asm files). 
 +  - The above programs must contain comments.
en/edu/zmitac/s1/apl/lab/lab4.1733397295.txt.gz · Last modified: by ktokarz