0%

Differentiating Between Local and Global Variable

  • Global variables are accessible by all functions loaded within a document(or drawing).
  • Local variables retain their value only as long as the function that defined them is running. After the function finishes running, the local variable values are automatically discarded, and the system reclaims the memory space the variable used.

Using Local Variable in the Program

1
2
3
4
5
6
7
8
9
(defun gp:getPointInput	(/ StartPt EndPt HalfWidth)
(if (setq StartPt (getpoint "\nStart point of path: "))
(if (setq EndPt (getpoint StartPt "\nEndpoint of path: "))
(if (setq HalfWidth (getdist EndPt "\nhalf-width of path: "))
T
)
)
)
)

The local variables are declared following the slash character.


Tutorial: Garden Path (Visual LISP IDE)

Reference

  • The Visual LISP® environment is introduced.
  • ActiveX® and Reactor functions of AutoLISP are demonstrated, as well as several other extensions to the AutoLISP language provided with Visual LISP.

There are two possible executino contexts for this tutorial:

  • The application may be run as interpreted LISP in piecemeal files and/ or functions that are loaded into a single document.
  • Or, the program code can be compiled into a VLX application, denoted by a *.vlx executable. A VLX operates from a self-contained namespace that can interact with the application-loading document.

Lesson 1: Designing and Beginning the Program(Visual LISP IDE)

Reference

Defining Overall Program Goals

Task

  • Given a start point, an endpoint, and a width, draw a rectilinear boundary. The boundary can be at any 2D orientation. There should be no limit on how large or small it can be.
  • Prompt the user for tile size and tile spacing values. The tiles are simple circles and will fill the boundary but must not overlap or cross the boundary.
  • Place the tiles in alternating rows.

Example Location can be found in:
C:\Program Files\Autodesk\AutoCAD 2022\Tutorial\VisualLISP

Getting Started With Visual LISP

First, it helps to demonstrate what can happen when Visual LISP is waiting for contorl to return from AutoCAD.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
;;; Function C:GPath is the main program function and defines the 
;;; AutoCAD GPATH command.
(defun C:GPath ()
;; Ask the user for input: first for path location and
;; direction, then for path parameters. Continue only if you have
;; valid input.
(if (gp:getPointInput) ;
(if (gp:getDialogInput)
(progn
;; At this point, you have valid input from the user.
;; Draw the outline, storing the resulting polyline
;; "pointer" in the variable called PolylineName.
(setq PolylineName (gp:drawOutline))
(princ "\nThe gp:drawOutline function returned <")
(princ PolylineName)
(princ ">")
(Alert "Congratulations - your program is complete!")
)
(princ "\nFunction cancelled.")
)
(princ "\nIncomplete information to draw a boundary.")
)
(princ) ; exit quietly
)
;;; Display a message to let the user know the command name.
(princ "\nType gpath to draw a garden path.")
(princ)
  • defun: declare the funcation
  • C:GPath : Command, and the name is GPath
  • gp:getPointInput and getDialogInput: These function names are prefixed with gp: to indicate they are specific to the graden path applcation. This is not a requiremnet
  • The final princ without a string argument forces the program to exit quietly.

Filling the Gaps in the program

  • pg:getPointInput
  • pg:getUserInput
  • gp:drawOutline
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
;;; Function gp:getPointInput will get path location and size
(defun gp:getPointInput ()
(alert
"Function gp:getPointInput will get user drawing input"
)
;; For now, return T, as if the function worked correctly.
T
)
;;; Function gp:getDialogInput will get path parameters
(defun gp:getDialogInput ()
(alert
"Function gp:getDialogInput will get user choices through a dialog"
)
;;For now, return T, as if the function worked correctly.
T
)
;;; Function gp:drawOutline will draw the path boundary
(defun gp:drawOutline ()
(alert
(strcat "This function will draw the outline of the polyline"
"\nand return a polyline entity name/pointer."
)
)
;; For now, simply return a quoted symbol. Eventually, this
;; function will return an entity name or pointer.
'SomeEname
)
  • The letter T is the symbol for “true” in AutoLISP
  • The way gpmain.lsp is structured, each input function it calls must return a value other than nil(no value) for the program to proceed to the next step.

An AutoLISP function will, by default, return the value of the last expression evaluated within it. In the stubbed-out functions, the only expression is a call to the alert function. But alert always returns nil. If this is left as the last expression in gp:getPointInput, it will always return nil, and you will never pass through the if to the gp:getDialogInput function.

For a similar reason, the end of the gp:DrawOutline function returns a quoted symbol (‘SomeEname) as a placeholder. A quoted symbol is a LISP construct that is not evaluated. (If you are curious about how the LISP language works, there are a number of good books available, mentioned at the end of this tutorial.)

Reference

https://help.autodesk.com/cloudhelp/2018/CHS/AutoCAD-AutoLISP-Tutorials/files/index.htm#!

Basic Tutorial

Tutoiral: Getting Started(AutoLISP)

Autodesk explanation Link

AutoLISP is based on the LISP(LISt Processing) programming
langauage.

A list is a structure enclosed by parentheses.

Usually, the first element in the list is the name of a function, and the following elements are called arguments.

1
(function_name [argument1 argumentX ...])

The ! (exclamation point) character can only be used at the AutoCAD Command prompt and is used to return the current value of an AutoLISP variable.


1
(+ 0.01 (* 2 0.875))
  • 2 * 0.875 = 1.75
  • 0.01 + 1.75 = 1.76

1
(setq nDist (getreal "\nEnter a distance: "))

The getreal function prompts the user for a real numeric value. The value provided is then passed to the setq function and assigned to the nDist user-defined variable.


1
(alert (strcat "Welcome" "to" "AutoLISP!"))

The stract function combines all the strings into a single string value. The value returned bt the strcat function is then passed to the alert function and displayed in a message box.

Tutoiral: Creating a New Custom Command and Controllign wiht System Variables(AutoLISP)

Your custom commands can use standard AutoCAD commands with the command function, or they can directly manipulate objects using AutoLISP functions.

Creating a New Function

defun means “define function.”

1
(defun function_name ([arguments] [/ local_variables ...]) expr ...)

The defun function also allows you to define a list of arguments that can be passed to the function and a list of user-defined variable that are “local” to the function.

1
2
3
4
5
6
7
(defun display-msg (msg mode / )
(if (= mode 0)
(prompt (strcat "\n" msg))
(alert msg)
)
(princ)
)
  • (display-msg “Hello from AutoLISP!” 0)
  • (display-msg “Hello from AutoLISP!” 1)

Creating a Custom Command

A custom command is a function that is defined with the defun function, but uses a special naming convention: they use the characters c: as a prefix. This distinguishes them from other functions.

You can define a function that accepts arguments, but you should never define a function that will be used as a custom command to accpet arguments.

1
2
3
4
(defun c:hello ( / msg)
(setq msg (getstring T "\nEnter a message: "))
(alert msg)
)

msg is a varible only exist inside the c:hello scope.

You can save your AutoLISP expressions to a file with the LSP file extension so they can be reused and loaded into other drawings.

Accessing and Setting System Variable Value

Getter/ Setter

  • getvar: Returns the current value of a system variable
  • setvar: Assigns a new value to a system variable

The following explain how to get and set the value of the OSMODE(Object Snap Mode) system varible.

  1. At the Command prompt, enter (setq cur_osmode (getvar “osmode”))
    The current value of the OSMODE system variable is returned and assigned to the user-defined variable of cur_osmode. While OSMODE returns an integer value, the value is the sum of multiple “bit-code“ values. For example, the value 35 indicates that the EndPoint(1), Midpoint(2) and Intersection(32) running object snaps are enabled.
  2. At the Command prompt, enter osnap

Creating, Loading, and Opening an AutoLISP File(AutoLISP)

AutoLISP is an interpretive language, so it can be stored in an ASCII text file, loaded, and then executed directly within AutoCAD.

AutoLISP files typically have an .lsp file extension, but they can also have the .mnl file extension. Both LSP and MNL files can be edited with a text editor.

MNL files are associated with user interface customization and they are automatically loaded into AutoCAD when a customization (CUI/ CUIx) file of the same name is loaded. For example, the acad.mnl is automatically loaded into AutoCAD when the acad.cuix file is loaded.

We can open any text editor create and .lsp file and load it into AutoCAD.

The way to load it into AutoCAD.

  • Manage > Application> Load Application(Find the correct file)

Preface

There are usually some recommendation videos from MIT OCW on youtube for me. Shameless to say, although I am interested in the courses, I never finished any whole semester. But, Nah. I just want to note down those I clicked and gain some knowledge after all.

Reference

https://www.youtube.com/watch?v=o7h_sYMk_oc&list=PLUl4u3cNGP63VIBQVWguXxZZi0566y7Wf&index=1

Software Properties

What software properties are more important than performace?

There are many things are more important than performance, but it doesn’t mean that performance is not important.

Performance is like some kind of currency(water resource).

Computer Programming in the Early Days

Software performace engineering was common, because machine resoures were limited.

Many programs strained the machine’s resources.

  • Programs had to be planned around the machine
  • Many program would not “fit” without intense performance engineering.

Clockrate, memory was low back in 70s

Clockrate

Core Speed = (Bus/Base Speed) * (Multiplier)

Lessons learned from the 70’s and 80’s

Premature optimization is the root of all evil. - Donald Knuth

More computing sins are committed in the name of efficiency(without necessarily achieving it) than for any other single reason - including blind stupidity -William Wulf

The First Rule of Program Optimization: Don’t do it. The Second Rule of Program Optimization - For experts only: Don’t do it yet. - Michael Jaskson

Making code readable and Fast

Vendor Solution: Multicore

Clock rate seem stop growing after around 2004.

  • To scale performance, processor manufacturers put many processing cores on the microprocessor chip
  • Each generation of Moore’s Law potentially doubles the number of cores.

Performance Is No Longer Free

Moore’s Law continues to increase computer performance.
But now that performance looks like big multicore processors with complex cache hierarchies, wide vector units, GPU’s, FGPA’s, etc

Generally, software must be adapted to utilize this hardware efficiently.

Same code writen in different language, Python, Java and C, for example

Interpreters are versatile, but slow

  • The interpreter reads, interprets, and preforms each program statement and updates the machine state.
  • Interpreters can easily support high-level programming features - such as dynamic code alteration - at the cost of performance

JIT compilation

  • JIT compilers can recover some of the performance lost by interpretation.
  • When code is first executed, it is interpreted.
  • The runtime system keeps track of how often the various pieces of code are executed.
  • Whenever some piece of code executes sufficiently frequently, it gets compiled to machine code in real time.
  • Future executions of that code use the more-efficient compiled version.

Performance of Differnent Order

Loop Order

1
2
3
4
5
6
7
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
for(int k = 0; k < n; k++){
c[i][j] += A[i][j] * B[k][j];
}
}
}

what if we change the order of the loops, let’s say,

1
2
3
4
5
6
7
        for(int k = 0; k < n; k++){
for(int j = 0; j < n; j++){
for(int i = 0; i < n; i++){
c[i][j] += A[i][j] * B[k][j];
}
}
}

Does this cause any performance difference?

cache location

Hardware Caches

Each processor reads and writes main memory in contiguous blocks, called cache lines.

  • Previously accessed cache lines are stored in a small memory, called a cache, that sits near the processor
  • Cache hits: accesses to data in cache -> are fast
  • Cache misses: accesses to data not in cache -> are slow

We can measure the effect of different access patterns using the Cachegrind cache simulator

1
valgrind --tool=cachegrind ./mm

Compiler Optimization

Clang provides a collection of optimization switches. You can specify a switch to the compiler to ask it to optimize.

Parallel Loops

The cilk_for loop allows all iterations of the loop to execute in parallel.

Experimenting with Parallel Loops

Parallel i Loop

1
2
3
4
5
6
7
clik_for(int i = 0; i < n; ++i){
for(int k =0; k < n ;++k){
for(int j =0; j < n ;++j){
c[i][j] += A[i][j] * B[k][j];
}
}
}

Running time: 3.18s

Parallel j Loop

1
2
3
4
5
6
7
for(int i = 0; i < n; ++i){
for(int k =0; k < n ;++k){
cilk_for(int j =0; j < n ;++j){
c[i][j] += A[i][j] * B[k][j];
}
}
}

Running time: 531.71s

Parallel i and j loops

1
2
3
4
5
6
7
cilk_for(int i = 0; i < n; ++i){
for(int k =0; k < n ;++k){
cilk_for(int j =0; j < n ;++j){
c[i][j] += A[i][j] * B[k][j];
}
}
}

Running time: 10.64s

For some reason, we cannot parallel k to get the correct answer.

Rule of Thumb: Parallelize outer loops rather than inner loops.

Using parallel loops gets us almost 18x speedup on 18 cores! (Disclaimer: Not all code is so easy to parallelize effictively.)

Vector Hardware

Modern microprocessors incorporate vector hardware to process data in single-instruction stream, multiple data stream(SIMD) fashion

Compiler Vectorization

Clang/LLVM uses vector instructions automatically when compiling at optimization level -02 or higher.

Many machines don’t support the newest set of vector instructions, however, so the compiler uses vector instructions conservatively by default.

Vectorization Flags

Programmers can direct the compiler to use modern vector instructions using compiler flags such as the following:

  • mavx: Use Intel AVX vector instructions
  • mavx2: Use Intel AVX2 vector instructions

Version Implementation

  1. Python
  2. Java
  3. C
  4. +interchange loops
  5. +optimization flags
  6. Parallel loops
  7. +tilling
  8. Parallel divide-and-conquer
  9. +compiler vectorization
  10. +AVX intrinsics

Plus More Optimizations

We can apply several more insights and performance-engineering trick to make this code run faster, including:

  • Preprocessing
  • Matrix transposition
  • Data alignment
  • Memory-managemnet optimizations
  • A clever algorithm for the base case that uses AVX intrinsic instructions explicitly