1 00:00:00,050 --> 00:00:02,480 The following content is provided under a Creative 2 00:00:02,480 --> 00:00:04,000 Commons license. 3 00:00:04,000 --> 00:00:06,340 Your support will help MIT OpenCourseWare 4 00:00:06,340 --> 00:00:10,710 continue to offer high quality educational resources for free. 5 00:00:10,710 --> 00:00:13,310 To make a donation or view additional materials 6 00:00:13,310 --> 00:00:17,216 from hundreds of MIT courses, visit MIT OpenCourseWare 7 00:00:17,216 --> 00:00:17,841 at ocw.mit.edu. 8 00:00:21,440 --> 00:00:24,119 PROFESSOR: So Phil is going to do the next three recitations. 9 00:00:24,119 --> 00:00:25,702 So the first one today is really going 10 00:00:25,702 --> 00:00:29,115 to focus on how do you actually debug programs on cell. 11 00:00:29,115 --> 00:00:31,490 How many people in here have used gdb, 12 00:00:31,490 --> 00:00:33,886 or are familiar with gdb? 13 00:00:33,886 --> 00:00:34,760 OK, good. 14 00:00:34,760 --> 00:00:37,350 So there's going to be a mini tutorial on how 15 00:00:37,350 --> 00:00:40,360 to run programs and attach gdb, which 16 00:00:40,360 --> 00:00:45,315 is a debugger that's commonly used for debugging programs. 17 00:00:45,315 --> 00:00:47,810 We'll show you how to debug PPU and SPU programs. 18 00:00:47,810 --> 00:00:50,940 And he's going to talk a little bit about some other things 19 00:00:50,940 --> 00:00:53,250 that might help you in terms of performance debugging, 20 00:00:53,250 --> 00:00:57,180 finding out where things are not going as well or as fast 21 00:00:57,180 --> 00:00:59,170 as you might expect them to. 22 00:00:59,170 --> 00:01:02,200 And the next two recitations, which will be next week, 23 00:01:02,200 --> 00:01:04,412 will focus on doing some actual performance-specific 24 00:01:04,412 --> 00:01:05,900 optimizations. 25 00:01:05,900 --> 00:01:07,300 So you've written your program. 26 00:01:07,300 --> 00:01:08,690 It's working. 27 00:01:08,690 --> 00:01:10,797 Well, the functionality is there. 28 00:01:10,797 --> 00:01:12,880 But it's not performing as fast as you might like. 29 00:01:12,880 --> 00:01:15,319 Or you think you can improve performance a bit better. 30 00:01:15,319 --> 00:01:16,110 So what can you do? 31 00:01:16,110 --> 00:01:18,730 So he'll show you some tricks and some things you can 32 00:01:18,730 --> 00:01:20,860 do to get the performance up. 33 00:01:20,860 --> 00:01:22,860 For some of you who have asked about the Eclipse 34 00:01:22,860 --> 00:01:27,710 debugger, the Eclipse IDE, it does run reasonably 35 00:01:27,710 --> 00:01:31,620 slowly on the PlayStation 3 because of memory constraints. 36 00:01:31,620 --> 00:01:35,540 So if you have lots of people trying to use it on the PS3, 37 00:01:35,540 --> 00:01:37,825 it'll probably be unusable. 38 00:01:37,825 --> 00:01:39,450 So for those of you who are interested, 39 00:01:39,450 --> 00:01:42,356 we'll just do separate tutorials offline. 40 00:01:42,356 --> 00:01:43,856 Because I don't know how many people 41 00:01:43,856 --> 00:01:45,260 will actually end up using it. 42 00:01:45,260 --> 00:01:46,610 Other than that, [INAUDIBLE]. 43 00:01:52,604 --> 00:01:53,270 PHIL: All right. 44 00:01:53,270 --> 00:01:56,780 So today we'll talk about how to run gdb on Cell. 45 00:01:56,780 --> 00:01:59,430 And then we'll also do some static profiling 46 00:01:59,430 --> 00:02:01,620 where you can figure out when instructions 47 00:02:01,620 --> 00:02:03,000 are going to be executed. 48 00:02:03,000 --> 00:02:05,660 And then I'll talk a little bit about the dynamic profiling 49 00:02:05,660 --> 00:02:06,868 tools that we have available. 50 00:02:11,140 --> 00:02:14,660 So you can use gdb to examine the state of your program. 51 00:02:14,660 --> 00:02:18,060 And this can help you figure out bugs that you might have. 52 00:02:18,060 --> 00:02:20,130 There's two ways that you can use gdb. 53 00:02:20,130 --> 00:02:23,389 The first way is when your program crashes, 54 00:02:23,389 --> 00:02:25,430 you can figure out what was happening at the time 55 00:02:25,430 --> 00:02:26,860 that it crashed. 56 00:02:26,860 --> 00:02:29,670 Another way that you can use gdb is to kind of run it 57 00:02:29,670 --> 00:02:30,590 from the beginning. 58 00:02:30,590 --> 00:02:33,290 You attach gdb to your program, and then you 59 00:02:33,290 --> 00:02:35,776 step through all the things, all the instructions that 60 00:02:35,776 --> 00:02:37,525 are being executed while the program runs. 61 00:02:42,080 --> 00:02:44,820 In order for gdb to be able to provide useful information 62 00:02:44,820 --> 00:02:46,550 about the state of your program, you 63 00:02:46,550 --> 00:02:48,030 have to give it a little help. 64 00:02:48,030 --> 00:02:52,200 You need to compile your program using gcc -g. 65 00:02:52,200 --> 00:02:53,860 xlc -g will also work. 66 00:02:58,042 --> 00:03:00,250 This puts in some extra information into your program 67 00:03:00,250 --> 00:03:05,630 so that when gdb is looking at the state of your program, 68 00:03:05,630 --> 00:03:08,810 it's able to figure out what line numbers in the source code 69 00:03:08,810 --> 00:03:11,820 that corresponds to. 70 00:03:11,820 --> 00:03:14,360 So you can just add dash g manually 71 00:03:14,360 --> 00:03:18,990 to your GCC invocations, or you can also set this compiler-- 72 00:03:18,990 --> 00:03:21,970 or you can set this option in the makefile, CC_OPT_LEVEL 73 00:03:21,970 --> 00:03:24,410 and set that to CC_OPT_LEVEL_DEBUG. 74 00:03:24,410 --> 00:03:29,060 And that will do the same thing as adding dash g. 75 00:03:29,060 --> 00:03:29,560 All right? 76 00:03:33,360 --> 00:03:36,530 Now we have a special version of gdb 77 00:03:36,530 --> 00:03:40,020 available for use on the Cell. 78 00:03:40,020 --> 00:03:44,950 ppu-gdb is used for debugging ppu and spu 79 00:03:44,950 --> 00:03:47,930 programs after they've been linked together. 80 00:03:47,930 --> 00:03:51,490 And how you invoke it if you're going 81 00:03:51,490 --> 00:03:56,760 to run your entire program using gdb is you type ppu-gdb 82 00:03:56,760 --> 00:03:58,800 and then the name of your program. 83 00:03:58,800 --> 00:04:00,600 And what you get is a gdb prompt where 84 00:04:00,600 --> 00:04:03,510 you can issue additional commands to the debugger 85 00:04:03,510 --> 00:04:06,090 to control execution of your program, 86 00:04:06,090 --> 00:04:07,994 and also ask the debugger to tell you 87 00:04:07,994 --> 00:04:09,410 various things about your program. 88 00:04:14,190 --> 00:04:17,600 One thing you can do is export SPU_INFO=1 before you start 89 00:04:17,600 --> 00:04:18,500 your program. 90 00:04:18,500 --> 00:04:22,120 And that will print some extra debugging information 91 00:04:22,120 --> 00:04:24,945 about when threads are being created and destroyed. 92 00:04:28,320 --> 00:04:32,100 Like I mentioned, you can also use gdb 93 00:04:32,100 --> 00:04:34,352 to attach to a program that's already running. 94 00:04:34,352 --> 00:04:36,060 And if you want to do that you still need 95 00:04:36,060 --> 00:04:38,870 to provide the executable name. 96 00:04:38,870 --> 00:04:42,190 And you also provide the process ID of the program to attach to. 97 00:04:45,304 --> 00:04:48,428 PROFESSOR: Do people know how to get the process ID? 98 00:04:48,428 --> 00:04:51,520 [INAUDIBLE] How many people don't know? 99 00:04:53,890 --> 00:04:55,765 The easiest way to do it is if your program's 100 00:04:55,765 --> 00:04:57,759 running just type "top." 101 00:04:57,759 --> 00:05:00,300 And that'll actually show you what's running on your machine. 102 00:05:00,300 --> 00:05:02,622 And there'll be a column that has a process ID. 103 00:05:02,622 --> 00:05:04,780 Another thing you can do is just type "ps." 104 00:05:04,780 --> 00:05:07,480 We'll add those to the recitation slides. [INAUDIBLE]. 105 00:05:10,472 --> 00:05:11,680 PHIL: So I forgot to mention. 106 00:05:11,680 --> 00:05:15,750 If you're invoking your program with gdb, 107 00:05:15,750 --> 00:05:21,205 then after you type ppu-gdb with your executable name, 108 00:05:21,205 --> 00:05:23,580 gdb is just going to sit there and wait for instructions. 109 00:05:23,580 --> 00:05:25,330 And what you can do is type "run" and that 110 00:05:25,330 --> 00:05:27,760 will run your program normally. 111 00:05:27,760 --> 00:05:30,200 But the difference is that gdb will pick up 112 00:05:30,200 --> 00:05:33,829 and if something goes wrong. 113 00:05:33,829 --> 00:05:36,370 And then that's where you can step in and look at the program 114 00:05:36,370 --> 00:05:36,870 state. 115 00:05:41,900 --> 00:05:44,630 So what kind of things can you figure out about your program? 116 00:05:47,260 --> 00:05:50,360 Anytime you have this gdb prompt and your program is running, 117 00:05:50,360 --> 00:05:54,597 you can type "bt" to get a stack trace for your program. 118 00:05:54,597 --> 00:05:56,180 And this will tell you which functions 119 00:05:56,180 --> 00:05:57,860 are calling which functions. 120 00:06:00,640 --> 00:06:03,340 It's going to give you a list of frames. 121 00:06:03,340 --> 00:06:04,950 And the top one is going to correspond 122 00:06:04,950 --> 00:06:07,540 to the deepest level of function nesting, 123 00:06:07,540 --> 00:06:11,060 or the deepest function call in the program. 124 00:06:11,060 --> 00:06:13,300 And of course, the last one on the list 125 00:06:13,300 --> 00:06:16,564 is going to be the main or the first function that was called. 126 00:06:16,564 --> 00:06:17,230 That make sense? 127 00:06:21,450 --> 00:06:26,220 And for each stack frame gdb will tell you 128 00:06:26,220 --> 00:06:27,680 the name of the function. 129 00:06:27,680 --> 00:06:29,110 And if source code is available it 130 00:06:29,110 --> 00:06:33,890 will tell you also which file the function is 131 00:06:33,890 --> 00:06:38,016 running in right now, and at which line number. 132 00:06:38,016 --> 00:06:39,390 And so using that information you 133 00:06:39,390 --> 00:06:43,280 can figure out exactly where it was that this function called 134 00:06:43,280 --> 00:06:46,250 the next function and where was that each function called 135 00:06:46,250 --> 00:06:47,550 the next function after that. 136 00:06:54,750 --> 00:06:57,620 Now whenever you've halted the program state, 137 00:06:57,620 --> 00:07:02,240 you can get information about what the local variables are. 138 00:07:02,240 --> 00:07:04,435 And to do that you can type "info locals" 139 00:07:04,435 --> 00:07:06,560 and it will print a list of all the local variables 140 00:07:06,560 --> 00:07:08,010 and their values. 141 00:07:08,010 --> 00:07:12,390 gdb, because it gets annotations from the compiled program, 142 00:07:12,390 --> 00:07:14,620 it knows about what data types are associated 143 00:07:14,620 --> 00:07:15,940 with which variables. 144 00:07:15,940 --> 00:07:22,250 And so it will be able to format the output appropriately. 145 00:07:22,250 --> 00:07:25,550 So for example, it knows that i is an integer. 146 00:07:25,550 --> 00:07:31,110 Whereas if you had i as, for example, a floating point 147 00:07:31,110 --> 00:07:34,410 number, it would print that floating point number 148 00:07:34,410 --> 00:07:37,160 representation instead. 149 00:07:37,160 --> 00:07:39,080 Instead of looking at single variables 150 00:07:39,080 --> 00:07:43,400 you can also ask gdb to evaluate arbitrary expressions for you. 151 00:07:43,400 --> 00:07:46,020 And this is actually a really powerful facility. 152 00:07:46,020 --> 00:07:48,410 You can pretty much type any expression that you would be 153 00:07:48,410 --> 00:07:50,505 able to use in C or C++. 154 00:07:58,880 --> 00:08:00,400 When you type "print VARNAME" gdb 155 00:08:00,400 --> 00:08:02,160 will look up that variable name for you. 156 00:08:02,160 --> 00:08:07,902 But sometimes if you have more than one variable 157 00:08:07,902 --> 00:08:09,860 available in your function under the same name, 158 00:08:09,860 --> 00:08:12,420 for example, these variables are in different files 159 00:08:12,420 --> 00:08:18,420 or different functions that are all available, 160 00:08:18,420 --> 00:08:21,649 then you may need to disambiguate the variable name. 161 00:08:21,649 --> 00:08:23,690 And to do that you just proceed the variable name 162 00:08:23,690 --> 00:08:27,250 with either the file name that you want to use or the function 163 00:08:27,250 --> 00:08:29,647 that the variable occurs in. 164 00:08:29,647 --> 00:08:30,230 Any questions? 165 00:08:35,580 --> 00:08:38,400 OK. 166 00:08:38,400 --> 00:08:45,480 And because gdb knows which line numbers the programs 167 00:08:45,480 --> 00:08:47,770 is executing right now, then it's 168 00:08:47,770 --> 00:08:50,280 able to show you the source code corresponding 169 00:08:50,280 --> 00:08:53,920 to the current place in the program. 170 00:08:53,920 --> 00:08:57,380 And in order to browse the source code, if it's available 171 00:08:57,380 --> 00:09:01,700 you just type "list." 172 00:09:01,700 --> 00:09:04,360 In general whenever gdb has stopped in a certain place 173 00:09:04,360 --> 00:09:08,130 you can type "list" to get a listing of the source 174 00:09:08,130 --> 00:09:10,240 code near that location. 175 00:09:10,240 --> 00:09:11,900 And what list will do, by default, 176 00:09:11,900 --> 00:09:16,850 is show 10 lines of source code near where the program stopped. 177 00:09:16,850 --> 00:09:20,240 If you type "list" again it will show 10 lines following that. 178 00:09:20,240 --> 00:09:24,450 And you can keep typing "list" to browse the source code. 179 00:09:24,450 --> 00:09:28,412 You can also get the code that's at a particular line number 180 00:09:28,412 --> 00:09:30,620 if you want to look at another place in your program. 181 00:09:35,430 --> 00:09:38,704 All right, so this is how to use gdb to actually control 182 00:09:38,704 --> 00:09:39,745 the flow of your program. 183 00:09:48,140 --> 00:09:51,100 If you invoke gdb to start up your program, 184 00:09:51,100 --> 00:09:54,400 then you can type "run" and that will run your program 185 00:09:54,400 --> 00:09:55,950 with a normal flow of execution. 186 00:09:55,950 --> 00:09:59,630 And it will only stop when errors occur. 187 00:09:59,630 --> 00:10:02,320 But you can use a couple of these commands 188 00:10:02,320 --> 00:10:05,200 to actually go step by step through your program. 189 00:10:05,200 --> 00:10:10,580 And wait for one line to be executed, and then 190 00:10:10,580 --> 00:10:13,970 decide whether you want to look at the next line or not. 191 00:10:13,970 --> 00:10:17,990 If you want to do this kind of step-by-step execution 192 00:10:17,990 --> 00:10:20,470 you start by using the start command instead 193 00:10:20,470 --> 00:10:23,110 of the run command, which will run continuously. 194 00:10:23,110 --> 00:10:26,960 Then anytime you want to jump to the next instruction, 195 00:10:26,960 --> 00:10:30,120 you can use next to get to the next line 196 00:10:30,120 --> 00:10:32,440 in the current procedure. 197 00:10:32,440 --> 00:10:34,705 You can also use step, which, if there 198 00:10:34,705 --> 00:10:36,330 are function calls on the current line, 199 00:10:36,330 --> 00:10:38,190 will descend into those function calls 200 00:10:38,190 --> 00:10:40,810 and show you what's going on over there. 201 00:10:40,810 --> 00:10:43,350 And if you're inside a function call 202 00:10:43,350 --> 00:10:47,300 you can type "finish" in order to jump 203 00:10:47,300 --> 00:10:49,430 back to right after the function call ends 204 00:10:49,430 --> 00:10:53,250 in the caller of that function. 205 00:10:53,250 --> 00:10:57,950 And if you want to stop line-by-line execution 206 00:10:57,950 --> 00:11:00,750 you can type "continue" and it will just 207 00:11:00,750 --> 00:11:03,080 continue without interruptions. 208 00:11:03,080 --> 00:11:03,720 Any questions? 209 00:11:06,860 --> 00:11:10,640 Basically any time you use one of these line-by-line commands 210 00:11:10,640 --> 00:11:13,840 gdb will show you the line that you're on. 211 00:11:13,840 --> 00:11:19,630 And if your program just jumped into a new function 212 00:11:19,630 --> 00:11:22,730 or something, then it will also show you what function 213 00:11:22,730 --> 00:11:24,820 and what file you're in. 214 00:11:24,820 --> 00:11:26,710 So this is very helpful for following what's 215 00:11:26,710 --> 00:11:27,770 going on in your program. 216 00:11:34,020 --> 00:11:34,840 OK. 217 00:11:34,840 --> 00:11:38,150 So in addition to just running through your program 218 00:11:38,150 --> 00:11:40,010 step by step, you can also choose 219 00:11:40,010 --> 00:11:43,970 to only stop your program when certain things happen. 220 00:11:43,970 --> 00:11:46,440 So this is very useful for debugging 221 00:11:46,440 --> 00:11:49,130 certain pieces of code where the code is very deeply 222 00:11:49,130 --> 00:11:52,950 nested inside and you don't want to step all the way to there. 223 00:11:52,950 --> 00:11:56,060 You just want to stop when you get there. 224 00:11:56,060 --> 00:11:59,390 And gdb allows you to define breakpoints, which 225 00:11:59,390 --> 00:12:02,430 are places in your source code. 226 00:12:02,430 --> 00:12:07,694 And once gdb gets to a point of execution which corresponds 227 00:12:07,694 --> 00:12:09,110 to that point in your source code, 228 00:12:09,110 --> 00:12:11,800 it will stop and ask you what to do. 229 00:12:11,800 --> 00:12:14,720 You can set a breakpoint that's associated 230 00:12:14,720 --> 00:12:17,710 with any particular function in your source code 231 00:12:17,710 --> 00:12:21,890 or any particular-- well, what you can do 232 00:12:21,890 --> 00:12:24,705 is if you do break function then it 233 00:12:24,705 --> 00:12:26,280 will create a new breakpoint. 234 00:12:26,280 --> 00:12:27,910 And it will stop execution any time 235 00:12:27,910 --> 00:12:31,050 you get to the beginning of that function. 236 00:12:31,050 --> 00:12:32,450 But you can also set break points 237 00:12:32,450 --> 00:12:38,450 in the interior of a function by using line numbers. 238 00:12:38,450 --> 00:12:40,330 All right? 239 00:12:40,330 --> 00:12:40,930 Any questions? 240 00:12:43,650 --> 00:12:48,080 Now sometimes you want a little bit more flexibility than that 241 00:12:48,080 --> 00:12:50,410 in setting breakpoints. 242 00:12:50,410 --> 00:12:52,330 If you only want to set a breakpoint 243 00:12:52,330 --> 00:12:55,660 to happen when a certain condition is true-- this 244 00:12:55,660 --> 00:12:58,500 is helpful if you're trying to track down a bug-- then 245 00:12:58,500 --> 00:13:01,630 you can write "break" and any of these things, 246 00:13:01,630 --> 00:13:03,870 and then "if expression." 247 00:13:03,870 --> 00:13:05,790 And again, you can use any sort of expression 248 00:13:05,790 --> 00:13:08,110 that you'd be able to use in C. 249 00:13:08,110 --> 00:13:11,660 And what gdb will do is every time execution 250 00:13:11,660 --> 00:13:14,060 runs up to that line it will evaluate the expression. 251 00:13:14,060 --> 00:13:16,780 And only if that expression is true will 252 00:13:16,780 --> 00:13:20,580 it stop to ask you for control. 253 00:13:20,580 --> 00:13:23,750 At any time you can see which breakpoints 254 00:13:23,750 --> 00:13:29,580 are active by doing info breakpoints at the gdb prompt. 255 00:13:29,580 --> 00:13:32,800 And you can also remove breakpoints at any time. 256 00:13:32,800 --> 00:13:36,830 When each breakpoint is created it's given this number. 257 00:13:36,830 --> 00:13:38,940 And the numbers start from one. 258 00:13:38,940 --> 00:13:42,452 And to remove a breakpoint you just do remove 259 00:13:42,452 --> 00:13:44,160 followed by the number that was assigned. 260 00:13:48,500 --> 00:13:52,530 In addition to breaking, you can also set a watchpoint. 261 00:13:52,530 --> 00:13:55,380 What this does is it will halt your program every time 262 00:13:55,380 --> 00:13:58,190 a particular value changes. 263 00:13:58,190 --> 00:14:02,870 And this is useful for tracking down certain kinds of bugs. 264 00:14:02,870 --> 00:14:04,870 If you're trying to figure out where 265 00:14:04,870 --> 00:14:08,291 a certain value for a variable came from, 266 00:14:08,291 --> 00:14:10,790 there could potentially be many, many places in your program 267 00:14:10,790 --> 00:14:12,470 where that value is set. 268 00:14:12,470 --> 00:14:15,200 And you don't want to have to set a breakpoint for all those 269 00:14:15,200 --> 00:14:16,370 and watch them. 270 00:14:16,370 --> 00:14:17,890 So you can instead set a watchpoint 271 00:14:17,890 --> 00:14:20,650 which will just tell you when that value is set. 272 00:14:24,060 --> 00:14:27,670 Watchpoints work a lot like breakpoints. 273 00:14:27,670 --> 00:14:31,346 If you do info breakpoints it will also list the watchpoints. 274 00:14:31,346 --> 00:14:32,720 And I believe you can also remove 275 00:14:32,720 --> 00:14:33,990 them the same way with remove. 276 00:14:39,580 --> 00:14:42,250 All right, so I mentioned how you can examine your program 277 00:14:42,250 --> 00:14:47,130 state by looking at the values of local variables. 278 00:14:47,130 --> 00:14:48,680 If you want a more low level view 279 00:14:48,680 --> 00:14:50,150 of what's going on in your program, 280 00:14:50,150 --> 00:14:53,870 you can actually look at the raw memory. 281 00:14:53,870 --> 00:14:58,860 And gdb allows you to specify an address. 282 00:14:58,860 --> 00:15:03,045 And it will tell you exactly what data is stored 283 00:15:03,045 --> 00:15:04,295 in the memory at that address. 284 00:15:08,530 --> 00:15:11,110 But because there's not necessarily annotation info 285 00:15:11,110 --> 00:15:14,490 telling gdb what kind of data is stored at that address, 286 00:15:14,490 --> 00:15:15,990 and of course, there's multiple ways 287 00:15:15,990 --> 00:15:19,080 you can interpret any particular piece of data, 288 00:15:19,080 --> 00:15:21,490 you'll have to tell gdb exactly how you want 289 00:15:21,490 --> 00:15:23,430 that data to be interpreted. 290 00:15:23,430 --> 00:15:25,960 So you can interpret any particular block of memory 291 00:15:25,960 --> 00:15:29,040 as, for example, a series of machine instructions. 292 00:15:29,040 --> 00:15:32,650 Then gdb will tell you what the instructions are as if you were 293 00:15:32,650 --> 00:15:36,920 looking at an assembly listing. 294 00:15:36,920 --> 00:15:38,670 You can ask gdb to interpret the memory as 295 00:15:38,670 --> 00:15:42,940 if it were an array of integers and print them out 296 00:15:42,940 --> 00:15:44,275 either in hex or in decimal. 297 00:15:47,940 --> 00:15:58,250 You can ask gdb to display the data as if they were addresses 298 00:15:58,250 --> 00:16:00,080 or floating point numbers. 299 00:16:00,080 --> 00:16:05,850 And how you do this is you type x for examine memory and slash. 300 00:16:05,850 --> 00:16:08,660 And then the number following is the number 301 00:16:08,660 --> 00:16:11,540 of words you want to look at. 302 00:16:11,540 --> 00:16:14,690 And then the letter corresponds to one of these letters 303 00:16:14,690 --> 00:16:18,160 and tells gdb how to format the output. 304 00:16:18,160 --> 00:16:20,690 And then the address will be the starting block of where you 305 00:16:20,690 --> 00:16:22,970 want to start examining memory. 306 00:16:22,970 --> 00:16:23,470 All right? 307 00:16:23,470 --> 00:16:24,511 Any questions about this? 308 00:16:32,590 --> 00:16:36,040 OK, so I mentioned that at any time when you stop your program 309 00:16:36,040 --> 00:16:39,180 there are going to be multiple function calls which 310 00:16:39,180 --> 00:16:41,511 are active, corresponding to main, which called 311 00:16:41,511 --> 00:16:43,760 this other function, which called this other function, 312 00:16:43,760 --> 00:16:46,837 which called wherever your current point of execution is. 313 00:16:46,837 --> 00:16:48,420 And you can actually examine the state 314 00:16:48,420 --> 00:16:51,505 for all of these stack frames separately. 315 00:16:54,310 --> 00:16:58,710 When you do bt it's going to give you the list of frames. 316 00:16:58,710 --> 00:17:00,540 And they're going to be numbered from 0 317 00:17:00,540 --> 00:17:03,480 to however many there are. 318 00:17:03,480 --> 00:17:10,470 And you can jump to any of them by using frame 319 00:17:10,470 --> 00:17:11,903 and the appropriate number. 320 00:17:11,903 --> 00:17:13,569 And it's going to default to frame zero, 321 00:17:13,569 --> 00:17:16,550 which is the closest to where your program is actually 322 00:17:16,550 --> 00:17:17,690 executing. 323 00:17:17,690 --> 00:17:22,280 But you can examine the state in frames which are further away. 324 00:17:22,280 --> 00:17:25,480 So that means when you're evaluating variables, 325 00:17:25,480 --> 00:17:27,839 each variable only makes sense in the context 326 00:17:27,839 --> 00:17:29,050 of a particular frame. 327 00:17:29,050 --> 00:17:32,240 And you're able to go up the call stack 328 00:17:32,240 --> 00:17:36,990 to figure out what the value of a particular variable 329 00:17:36,990 --> 00:17:41,370 is in this function, which called this other function. 330 00:17:41,370 --> 00:17:43,140 You can also use the commands up and down 331 00:17:43,140 --> 00:17:49,320 to just jump to the immediately adjacent frames. 332 00:17:49,320 --> 00:17:49,820 All right? 333 00:17:54,460 --> 00:17:57,870 OK, so you can use gdb from emacs as well. 334 00:17:57,870 --> 00:18:02,300 And emacs provides a really handy interface for gdb. 335 00:18:02,300 --> 00:18:05,830 If you do M-x gdb emacs will invoke gdb for you. 336 00:18:05,830 --> 00:18:09,310 And when you do this, you're going 337 00:18:09,310 --> 00:18:14,100 to want to tell emacs to use ppu gdb instead of regular gdb. 338 00:18:14,100 --> 00:18:16,470 And emacs will just ask you what you want to invoke. 339 00:18:16,470 --> 00:18:21,270 You just want to replace gdb with ppu gdb. 340 00:18:21,270 --> 00:18:24,860 Anytime you're debugging within emacs, 341 00:18:24,860 --> 00:18:27,480 if emacs has your source code files open, 342 00:18:27,480 --> 00:18:29,470 it will show you the current point of execution 343 00:18:29,470 --> 00:18:35,840 by drawing a little arrow next to the particular line 344 00:18:35,840 --> 00:18:36,700 in the buffer. 345 00:18:40,320 --> 00:18:42,120 You also get a bunch of keyboard shortcuts 346 00:18:42,120 --> 00:18:46,010 that you can use to do some common operations. 347 00:18:46,010 --> 00:18:48,470 You can set breakpoints with Control X Space, 348 00:18:48,470 --> 00:18:53,020 just by placing your cursor at the particular line 349 00:18:53,020 --> 00:18:54,260 that you want to stop at. 350 00:18:54,260 --> 00:18:57,580 So you don't have to go to gdb and type break 351 00:18:57,580 --> 00:18:58,330 whatever whatever. 352 00:19:01,440 --> 00:19:03,810 But when you do m-x gdb in emacs, 353 00:19:03,810 --> 00:19:05,589 you get a separate buffer for gdb. 354 00:19:05,589 --> 00:19:07,880 And so you can issue all the commands that you normally 355 00:19:07,880 --> 00:19:08,470 would want to. 356 00:19:12,330 --> 00:19:14,430 OK, so the first thing we're going 357 00:19:14,430 --> 00:19:16,830 to try-- this should be really quick-- 358 00:19:16,830 --> 00:19:23,750 is we're just going to open up a brief program 359 00:19:23,750 --> 00:19:27,230 and make sure you can invoke gdb on it. 360 00:19:37,880 --> 00:19:40,300 And you'll have to set Cell top if you 361 00:19:40,300 --> 00:19:41,530 don't have that set already. 362 00:19:53,620 --> 00:19:55,609 I'm just going to do it on the same one. 363 00:19:55,609 --> 00:19:57,461 [INAUDIBLE] 364 00:19:57,461 --> 00:20:00,240 AUDIENCE: How do you exit gdb again? 365 00:20:00,240 --> 00:20:12,770 PHIL: Oh, you can do Quit or Control D. 366 00:20:12,770 --> 00:20:15,960 So once you've attached gdb to a program, when you exit gdb 367 00:20:15,960 --> 00:20:18,300 it will quit the program that you were running, 368 00:20:18,300 --> 00:20:19,875 unless you do detach first. 369 00:20:22,307 --> 00:20:23,890 For this one it doesn't really matter, 370 00:20:23,890 --> 00:20:25,777 because we're looking at a crash anyway. 371 00:20:31,621 --> 00:20:35,517 PROFESSOR: [INAUDIBLE] Anybody [INAUDIBLE]? 372 00:20:38,439 --> 00:20:39,900 OK. 373 00:20:39,900 --> 00:20:44,320 AUDIENCE: How do you evaluate something [INAUDIBLE]? 374 00:20:44,320 --> 00:20:47,720 PHIL: You can evaluate an expression using Print. 375 00:20:51,740 --> 00:20:52,995 OK, any questions? 376 00:20:56,350 --> 00:20:58,760 All right, so all I did here was run 377 00:20:58,760 --> 00:21:01,530 and then the program crashes. 378 00:21:01,530 --> 00:21:12,420 This is just lab one without the alignment in the control block 379 00:21:12,420 --> 00:21:15,570 that you need to make everything work correctly. 380 00:21:15,570 --> 00:21:17,590 And so all I did here was run and then 381 00:21:17,590 --> 00:21:20,040 the program crashes and then print cb. 382 00:21:20,040 --> 00:21:21,700 And of course, this thing is going 383 00:21:21,700 --> 00:21:26,711 to be 0 because the DMA transfer to do that doesn't work. 384 00:21:26,711 --> 00:21:27,210 Questions? 385 00:21:30,370 --> 00:21:34,520 OK so we can exit the debugger with Control D. 386 00:21:34,520 --> 00:21:37,060 And it'll ask if you want to kill the program. 387 00:21:45,900 --> 00:21:48,300 So gdb also has features to help you 388 00:21:48,300 --> 00:21:52,440 with debugging programs that have multiple threads. 389 00:21:52,440 --> 00:21:58,680 Whenever a new thread is created or a thread is destroyed, 390 00:21:58,680 --> 00:22:01,350 gdb will print a brief message to tell you. 391 00:22:01,350 --> 00:22:08,420 And one important thing is it will print this LWP number 392 00:22:08,420 --> 00:22:09,290 on the PlayStations. 393 00:22:14,280 --> 00:22:17,650 To get a list of threads you can type info threads. 394 00:22:17,650 --> 00:22:19,530 And gdb always maintains this thing 395 00:22:19,530 --> 00:22:20,850 called the current thread. 396 00:22:20,850 --> 00:22:25,360 And by default, when you do many of these other actions 397 00:22:25,360 --> 00:22:28,560 they're going to apply to the current thread. 398 00:22:28,560 --> 00:22:31,510 And so to examine things about other threads 399 00:22:31,510 --> 00:22:33,270 you're going to have to change the thread. 400 00:22:33,270 --> 00:22:36,890 And to do that you do thread and some number. 401 00:22:36,890 --> 00:22:38,920 When you do info threads, it's going 402 00:22:38,920 --> 00:22:40,880 to give you this list of threads which 403 00:22:40,880 --> 00:22:44,190 are numbered, for example, 1, 2, 3 on the left. 404 00:22:44,190 --> 00:22:47,086 And the LWP numbers that are displayed 405 00:22:47,086 --> 00:22:48,960 are going to correspond to these that came up 406 00:22:48,960 --> 00:22:52,005 when the threads were started. 407 00:22:52,005 --> 00:22:54,380 But you're going to have to use these numbers on the left 408 00:22:54,380 --> 00:22:56,580 to switch between threads. 409 00:22:56,580 --> 00:22:58,600 And when you do info threads, gdb 410 00:22:58,600 --> 00:23:01,650 will mark the current thread with a star on the left. 411 00:23:01,650 --> 00:23:03,770 And it will also show you where each thread 412 00:23:03,770 --> 00:23:05,185 is executing right now. 413 00:23:05,185 --> 00:23:05,685 Questions? 414 00:23:10,475 --> 00:23:12,349 AUDIENCE: Where does it show you [INAUDIBLE]? 415 00:23:17,300 --> 00:23:21,230 PHIL: It will show the procedure and the file name and line 416 00:23:21,230 --> 00:23:26,020 number, if that information is available. 417 00:23:26,020 --> 00:23:28,370 PROFESSOR: If you can't find out which [INAUDIBLE]. 418 00:23:28,370 --> 00:23:30,250 AUDIENCE: That's what I was saying-- 419 00:23:30,250 --> 00:23:31,700 PHIL: Ah. 420 00:23:31,700 --> 00:23:33,700 No. 421 00:23:33,700 --> 00:23:36,317 AUDIENCE: [INAUDIBLE] 422 00:23:36,317 --> 00:23:38,650 PROFESSOR: I don't believe you can get that information. 423 00:23:38,650 --> 00:23:39,630 We can check. 424 00:23:42,570 --> 00:23:45,985 David, do you know? 425 00:23:45,985 --> 00:23:49,430 Sorry [INAUDIBLE]. 426 00:23:49,430 --> 00:23:51,075 So David says maybe you can do it 427 00:23:51,075 --> 00:23:53,015 on a simulator, but not [INAUDIBLE]. 428 00:23:57,380 --> 00:23:59,400 PHIL: OK. 429 00:23:59,400 --> 00:24:01,920 So we're going to try this brief exercise, which 430 00:24:01,920 --> 00:24:07,630 is just to get you to work with dealing with multiple threads. 431 00:24:07,630 --> 00:24:12,160 And what you're going to do is load the lab 1 432 00:24:12,160 --> 00:24:16,200 program, which is the correctly working solution for lab 1. 433 00:24:16,200 --> 00:24:20,430 And if you'll recall, this program has multiple threads. 434 00:24:20,430 --> 00:24:24,452 The PPU thread maintains an array of control blocks. 435 00:24:24,452 --> 00:24:26,660 And it's going to send the addresses of those control 436 00:24:26,660 --> 00:24:28,695 blocks to the SPUs. 437 00:24:28,695 --> 00:24:30,320 So what we're going to do is we're just 438 00:24:30,320 --> 00:24:32,960 going to set breakpoints at the right places 439 00:24:32,960 --> 00:24:39,760 to verify that the first SPU thread is getting the control 440 00:24:39,760 --> 00:24:41,880 block which is the same as one of the control 441 00:24:41,880 --> 00:24:43,990 blocks in the PPU program. 442 00:24:43,990 --> 00:24:45,930 All right, any questions about that? 443 00:24:45,930 --> 00:24:47,820 This is in [? rec ?] 4, lab 1. 444 00:24:53,470 --> 00:24:56,700 So you're going to have to run and set breakpoints 445 00:24:56,700 --> 00:24:58,000 at the right places. 446 00:24:58,000 --> 00:25:00,840 And you're going to want to set one break point in each thread 447 00:25:00,840 --> 00:25:05,083 to be able to examine the value of CB that's being produced. 448 00:26:10,380 --> 00:26:13,940 PROFESSOR: [INAUDIBLE] right after the recitation. 449 00:26:13,940 --> 00:26:16,490 As another exercise for those of you who did get through, 450 00:26:16,490 --> 00:26:18,720 the way you'll actually run into these problems 451 00:26:18,720 --> 00:26:20,180 is you'll run your program and you 452 00:26:20,180 --> 00:26:21,660 might end up with a bus error. 453 00:26:21,660 --> 00:26:24,310 So what you might want to do is then launch gdb. 454 00:26:24,310 --> 00:26:26,230 And you run to the error. 455 00:26:26,230 --> 00:26:28,320 And then you trace back in the execution to see, 456 00:26:28,320 --> 00:26:31,441 uh-oh, is my control block value matching? 457 00:26:31,441 --> 00:26:33,982 So you might want to try that for the second exercise online. 458 00:26:40,210 --> 00:26:42,437 PHIL: Should do the stack profiling thing? 459 00:26:42,437 --> 00:26:45,416 PROFESSOR: Yeah, just go through that. [INAUDIBLE]. 460 00:26:45,416 --> 00:26:45,916 PHIL: OK. 461 00:26:50,400 --> 00:26:52,160 So one problem that you may have run into 462 00:26:52,160 --> 00:26:57,300 is that gdb will remove breakpoints from threads 463 00:26:57,300 --> 00:27:00,320 that exit, which is a problem if you have more than one thread 464 00:27:00,320 --> 00:27:03,220 running the same program. 465 00:27:03,220 --> 00:27:05,590 And if you're debugging SPU programs, 466 00:27:05,590 --> 00:27:08,510 gdb may complain about not being able to find the source files. 467 00:27:08,510 --> 00:27:12,880 But if you just ignore that message, 468 00:27:12,880 --> 00:27:17,020 it seems to find them OK, I think. 469 00:27:17,020 --> 00:27:21,362 You can use SPU gdb to debug the SPU programs by themselves. 470 00:27:21,362 --> 00:27:22,445 You can try that sometime. 471 00:27:28,790 --> 00:27:31,819 OK, so actually figuring out what the errors are, 472 00:27:31,819 --> 00:27:33,860 unfortunately you don't get very much information 473 00:27:33,860 --> 00:27:35,860 from the actual errors that occur. 474 00:27:35,860 --> 00:27:38,150 But maybe looking at where the errors are occurring 475 00:27:38,150 --> 00:27:41,170 can help you figure things out. 476 00:27:41,170 --> 00:27:44,060 If you've run into memory misalignment 477 00:27:44,060 --> 00:27:49,910 problems or the problem in the last recitation where 478 00:27:49,910 --> 00:27:52,270 we had DMA transfers that were too big, 479 00:27:52,270 --> 00:27:54,140 those are all going to be bus errors. 480 00:27:54,140 --> 00:27:55,760 Under various other circumstances 481 00:27:55,760 --> 00:27:58,720 you might get segmentation faults. 482 00:27:58,720 --> 00:28:01,820 And if you think your program is running into a deadlock, 483 00:28:01,820 --> 00:28:06,540 you can also use gdb to kind of attach to the program 484 00:28:06,540 --> 00:28:08,360 and then examine the state of that program 485 00:28:08,360 --> 00:28:10,930 to see what's waiting for what. 486 00:28:13,830 --> 00:28:17,180 OK, so static profiling. 487 00:28:17,180 --> 00:28:18,680 We have some tools for the Cell that 488 00:28:18,680 --> 00:28:27,760 will allow you to, when you have a sequence of assembly 489 00:28:27,760 --> 00:28:30,850 instructions, figure out when those instructions are going 490 00:28:30,850 --> 00:28:33,310 to get scheduled and how fast the resulting sequence will 491 00:28:33,310 --> 00:28:34,209 run. 492 00:28:34,209 --> 00:28:35,750 So in order to take advantage of this 493 00:28:35,750 --> 00:28:40,030 you need to use GCC dash big S to generate your assembly. 494 00:28:40,030 --> 00:28:43,656 And you can also do that with xlc. 495 00:28:43,656 --> 00:28:45,030 If you're using our makefiles you 496 00:28:45,030 --> 00:28:48,400 can also use make whatever file named dot s in order 497 00:28:48,400 --> 00:28:54,020 to generate the assembly from your source code. 498 00:28:54,020 --> 00:28:56,430 Then once you have the dot s file 499 00:28:56,430 --> 00:28:59,070 you can run this utility called SPU timing. 500 00:28:59,070 --> 00:29:03,150 And what SPU timing does is it will 501 00:29:03,150 --> 00:29:05,750 take all the instructions that are in your assembly 502 00:29:05,750 --> 00:29:08,676 and figure out the dependencies between them. 503 00:29:08,676 --> 00:29:10,550 And then it will figure out when the earliest 504 00:29:10,550 --> 00:29:13,020 point is that each instruction can get executed. 505 00:29:13,020 --> 00:29:17,110 And it will print out the schedule that's generated. 506 00:29:17,110 --> 00:29:21,460 So if you provide the dash running count option, 507 00:29:21,460 --> 00:29:25,840 then it will also show you how many 508 00:29:25,840 --> 00:29:33,040 cycles in all the entire program will take. 509 00:29:33,040 --> 00:29:36,470 And the output goes into file name dot s dot timing. 510 00:29:42,570 --> 00:29:45,170 So for how instructions are scheduled on Cell, if you'll 511 00:29:45,170 --> 00:29:49,780 recall, there's two pipelines for different kinds 512 00:29:49,780 --> 00:29:50,520 of instructions. 513 00:29:50,520 --> 00:29:52,841 And some instructions can only run on one 514 00:29:52,841 --> 00:29:54,090 or the other of the pipelines. 515 00:29:54,090 --> 00:29:55,870 And some instructions can run on both. 516 00:29:58,480 --> 00:30:01,530 Now, how Cell actually schedules those instructions is 517 00:30:01,530 --> 00:30:03,980 it's always going to go in order that the instructions are 518 00:30:03,980 --> 00:30:08,730 specified in the binary. 519 00:30:08,730 --> 00:30:15,580 And whenever there's two instructions next to each other 520 00:30:15,580 --> 00:30:18,610 and the first instruction can run on pipeline zero 521 00:30:18,610 --> 00:30:21,810 and the second instruction can run on pipeline one, 522 00:30:21,810 --> 00:30:25,140 then Cell will try and schedule those at the same time. 523 00:30:25,140 --> 00:30:27,270 And that's called dual issue. 524 00:30:27,270 --> 00:30:29,460 So if you were taking advantage of that dual issue 525 00:30:29,460 --> 00:30:30,876 all the time, then potentially you 526 00:30:30,876 --> 00:30:33,210 could schedule two instructions every cycle. 527 00:30:39,100 --> 00:30:43,450 Oh yes, and unlike a lot of other architectures nowadays, 528 00:30:43,450 --> 00:30:46,310 Cell does not have dynamic rent branch prediction. 529 00:30:46,310 --> 00:30:53,020 All the branch prediction is encoded inside the assembly 530 00:30:53,020 --> 00:30:54,260 that you're using. 531 00:30:54,260 --> 00:30:57,920 So that means for any type of loop or whatever, 532 00:30:57,920 --> 00:31:01,010 you have to be sure to get the branch prediction right. 533 00:31:01,010 --> 00:31:03,850 If the branch prediction is wrong, 534 00:31:03,850 --> 00:31:06,310 Cell is going to end up pre-fetching instructions 535 00:31:06,310 --> 00:31:07,480 along the wrong line. 536 00:31:07,480 --> 00:31:13,370 And it's going to have to stall by about 20 cycles 537 00:31:13,370 --> 00:31:15,500 when it figures out that the branch is wrong. 538 00:31:21,050 --> 00:31:24,560 So if you're looking at the generated assembly on Cell, 539 00:31:24,560 --> 00:31:28,230 all the instructions are going to be of the form operation, 540 00:31:28,230 --> 00:31:34,600 then the destination register, and then two or more sources. 541 00:31:34,600 --> 00:31:37,920 And if you're trying to just kind of orient yourself 542 00:31:37,920 --> 00:31:39,940 in the generated assembly, there are sometimes 543 00:31:39,940 --> 00:31:42,730 these helpful markers. 544 00:31:42,730 --> 00:31:46,360 So if you're looking at the generated assembly 545 00:31:46,360 --> 00:31:49,450 for dist_spu, then it's going to have 546 00:31:49,450 --> 00:31:52,010 a header at the top which says which files 547 00:31:52,010 --> 00:31:57,120 were included inside this file. 548 00:31:57,120 --> 00:31:59,180 And then where the actual assembly 549 00:31:59,180 --> 00:32:04,140 is there'll be these markers that say, for example, location 550 00:32:04,140 --> 00:32:05,360 1 19. 551 00:32:05,360 --> 00:32:09,080 And what this means is that here is the assembly corresponding 552 00:32:09,080 --> 00:32:11,902 to file 1 line 19. 553 00:32:11,902 --> 00:32:13,360 So that's kind of helpful if you're 554 00:32:13,360 --> 00:32:17,970 trying to get your bearings inside the assembly. 555 00:32:17,970 --> 00:32:21,500 Because otherwise it's really hard to make heads or tails of. 556 00:32:21,500 --> 00:32:22,000 Questions? 557 00:32:24,960 --> 00:32:27,140 All right, so after you actually run your assembly 558 00:32:27,140 --> 00:32:30,420 through the static profiler, it will spit out this schedule. 559 00:32:30,420 --> 00:32:35,450 And what the schedule shows is which clock cycles are used 560 00:32:35,450 --> 00:32:38,230 for every single instruction. 561 00:32:38,230 --> 00:32:40,730 There's one line for each assembly instruction. 562 00:32:40,730 --> 00:32:42,470 And what it's going to do is it's 563 00:32:42,470 --> 00:32:45,980 going to print one digit in this schedule for each cycle 564 00:32:45,980 --> 00:32:49,070 that the instruction takes. 565 00:32:49,070 --> 00:32:51,300 All right? 566 00:32:51,300 --> 00:32:53,420 So you can kind of think of this dimension 567 00:32:53,420 --> 00:32:54,990 as the passage of time. 568 00:32:54,990 --> 00:32:58,219 And what happens is that these guys, 569 00:32:58,219 --> 00:32:59,760 when they get to the right-hand side, 570 00:32:59,760 --> 00:33:01,740 they'll wrap around it 50 columns or whatever. 571 00:33:05,840 --> 00:33:08,410 And you'll be able to notice when these instructions are 572 00:33:08,410 --> 00:33:09,380 being scheduled. 573 00:33:09,380 --> 00:33:12,040 And sometimes when there's dependencies 574 00:33:12,040 --> 00:33:14,520 between instructions, the instructions 575 00:33:14,520 --> 00:33:19,960 are not able to get scheduled at the earliest possible time. 576 00:33:19,960 --> 00:33:22,580 And when that happens you'll see these dashes, 577 00:33:22,580 --> 00:33:25,580 which mean that the instruction is being stalled to wait 578 00:33:25,580 --> 00:33:27,467 for one of the dependencies. 579 00:33:27,467 --> 00:33:29,050 In order to make your code fast you're 580 00:33:29,050 --> 00:33:33,270 going to want to eliminate these stalls. 581 00:33:33,270 --> 00:33:34,900 And you can do that to a large extent 582 00:33:34,900 --> 00:33:36,490 by reordering your instructions. 583 00:33:40,276 --> 00:33:42,716 AUDIENCE: Can you stop at the previous slide? 584 00:33:42,716 --> 00:33:43,264 PHIL: Yep. 585 00:33:43,264 --> 00:33:44,180 PROFESSOR: [INAUDIBLE] 586 00:33:48,100 --> 00:33:48,699 PHIL: Pardon? 587 00:33:48,699 --> 00:33:50,615 PROFESSOR: The point of instruction scheduling 588 00:33:50,615 --> 00:33:53,317 [INAUDIBLE]. 589 00:33:53,317 --> 00:33:55,150 PHIL: So the point of instruction scheduling 590 00:33:55,150 --> 00:33:58,550 is going to be to minimize the number of stalls. 591 00:34:02,420 --> 00:34:06,454 And you can do that by, if you have instructions which 592 00:34:06,454 --> 00:34:08,620 are going to be dependencies for other instructions, 593 00:34:08,620 --> 00:34:13,394 you just want to move those as far up as you can. 594 00:34:13,394 --> 00:34:16,454 PROFESSOR: So ideally you would get to instructions per cycle, 595 00:34:16,454 --> 00:34:18,770 or how many instructions can you use per cycle? 596 00:34:18,770 --> 00:34:21,795 Two, because you can have dual issue, two pipelines. 597 00:34:21,795 --> 00:34:25,800 Or how many cycles per instruction [INAUDIBLE] 598 00:34:25,800 --> 00:34:26,493 by a half. 599 00:34:26,493 --> 00:34:28,576 Because you're getting two instructions per cycle, 600 00:34:28,576 --> 00:34:30,210 so [INAUDIBLE]. 601 00:34:30,210 --> 00:34:32,810 So we have an exercise that actually 602 00:34:32,810 --> 00:34:34,750 has you understand the assembly code, 603 00:34:34,750 --> 00:34:37,004 and then doing the instruction reordering. 604 00:34:37,004 --> 00:34:38,420 So we'll leave that on the slides. 605 00:34:38,420 --> 00:34:39,336 You can do it offline. 606 00:34:39,336 --> 00:34:41,530 But we'll pick up with this next week 607 00:34:41,530 --> 00:34:45,300 and go over instruction scheduling, some DMA tricks 608 00:34:45,300 --> 00:34:46,840 for improving performance. 609 00:34:46,840 --> 00:34:50,409 And in particular, the thing we'll focus on quite rigorously 610 00:34:50,409 --> 00:34:51,694 is [INAUDIBLE]. 611 00:34:51,694 --> 00:34:53,860 So Phil's going to walk you through how you actually 612 00:34:53,860 --> 00:34:55,401 [? synchronize ?] and get performance 613 00:34:55,401 --> 00:34:58,884 from the vectorization and the intrinsics. 614 00:34:58,884 --> 00:35:02,090 We'll talk a little bit about [? heat ?] dynamic profiling. 615 00:35:02,090 --> 00:35:04,812 And for those of you who are still having problems with gdp, 616 00:35:04,812 --> 00:35:07,408 we'll try to resolve those now since it'll probably be 617 00:35:07,408 --> 00:35:10,080 very useful for your projects. 618 00:35:10,080 --> 00:35:14,725 And we installed CVS in the main directory on every PS3, 619 00:35:14,725 --> 00:35:16,141 for those of you who actually want 620 00:35:16,141 --> 00:35:18,224 to use it and go through the trouble of setting up 621 00:35:18,224 --> 00:35:19,722 their own CVS. 622 00:35:19,722 --> 00:35:21,910 The CVS that's satisfied actually 623 00:35:21,910 --> 00:35:24,210 notified the local users on that machine. 624 00:35:24,210 --> 00:35:26,200 So that would be everybody on your team. 625 00:35:26,200 --> 00:35:27,991 It will send out an email whenever somebody 626 00:35:27,991 --> 00:35:29,917 does a check-in or an import, to let 627 00:35:29,917 --> 00:35:32,125 them know that there's some new information that they 628 00:35:32,125 --> 00:35:33,664 don't want to update. 629 00:35:33,664 --> 00:35:36,080 If you don't know how to use CVS or want a quick tutorial, 630 00:35:36,080 --> 00:35:36,680 just stop by. 631 00:35:36,680 --> 00:35:38,780 Some of the TAs will be able to help you. 632 00:35:38,780 --> 00:35:40,880 OK? 633 00:35:40,880 --> 00:35:42,430 [INAUDIBLE]