00:10:53 | * | Jehan_ quit (Quit: Leaving) |
00:25:19 | * | DAddYE_ joined #nimrod |
00:25:20 | * | DAddYE quit (Read error: Connection reset by peer) |
00:40:57 | * | xenagi joined #nimrod |
00:54:27 | * | joelmo quit (Quit: Connection closed for inactivity) |
00:57:01 | * | q66 quit (Quit: Leaving) |
01:05:07 | * | DAddYE_ quit (Remote host closed the connection) |
01:12:19 | * | BitPuffin joined #nimrod |
01:55:09 | * | brson joined #nimrod |
01:56:36 | * | sdw quit (Read error: Connection reset by peer) |
02:00:38 | * | DAddYE joined #nimrod |
02:48:13 | * | hoverbear joined #nimrod |
03:27:38 | Varriount | Hm. Should nimrod's file opening procedure be made to use createFile and _open_osfhandle under the hood, to prevent locking the opened file? |
03:27:50 | * | xenagi quit (Quit: Leaving) |
03:28:51 | Varriount | dom96: Does anyone besides you have access to the website? |
03:30:43 | * | def- joined #nimrod |
03:34:05 | * | def-_ quit (Ping timeout: 252 seconds) |
03:36:09 | Varriount | We could also give a 'lock' boolean to the file opening procedure, Linux, BSD, and Mac OSX have flopen |
03:48:43 | * | saml_ quit (Ping timeout: 240 seconds) |
04:03:05 | * | Varriount|Mobile joined #nimrod |
04:07:12 | * | DAddYE quit (Remote host closed the connection) |
04:07:47 | * | DAddYE joined #nimrod |
04:11:55 | * | DAddYE quit (Ping timeout: 240 seconds) |
04:21:38 | * | flaviu quit (Ping timeout: 240 seconds) |
04:35:55 | * | DAddYE joined #nimrod |
04:51:59 | * | brson quit (Quit: leaving) |
04:52:44 | * | DAddYE quit (Remote host closed the connection) |
05:36:49 | * | bjz quit (Read error: Connection reset by peer) |
05:36:53 | * | BitPuffin quit (Ping timeout: 264 seconds) |
05:37:45 | * | bjz joined #nimrod |
05:50:06 | * | hoverbear quit () |
05:50:21 | * | hoverbear joined #nimrod |
05:53:23 | * | hoverbear quit (Client Quit) |
06:01:25 | * | zahary joined #nimrod |
06:45:28 | * | BitPuffin joined #nimrod |
07:20:24 | * | kunev joined #nimrod |
07:23:22 | * | MayurYa joined #nimrod |
07:37:16 | araq | hi MayurYa welcome |
07:39:33 | MayurYa | thanks for welcoming! |
07:44:48 | araq | I'm the greeting bot. :-) |
07:45:00 | araq | (nah, just kidding) |
07:48:41 | * | io2 joined #nimrod |
08:00:23 | * | kemet joined #nimrod |
08:09:55 | MayurYa | hehe! |
08:29:54 | * | kunev quit (Quit: leaving) |
08:30:02 | * | kunev joined #nimrod |
08:35:25 | * | kemet quit (Remote host closed the connection) |
08:59:27 | * | gsingh93_ quit (Quit: Connection closed for inactivity) |
09:28:18 | * | dirkk0 joined #nimrod |
09:34:51 | * | ehaliewicz quit (Ping timeout: 272 seconds) |
10:16:20 | * | kunev quit (Quit: leaving) |
10:16:35 | * | kunev joined #nimrod |
10:20:34 | * | dirkk0 quit (Quit: This computer has gone to sleep) |
10:27:36 | MayurYa | @araq still greeting? :wink |
11:08:27 | * | MayurYa quit (Quit: *nix server crashed w/ bof) |
12:13:22 | * | Varriount|Mobile quit (Read error: Connection reset by peer) |
12:13:28 | * | Varriount-Mobile joined #nimrod |
12:17:09 | * | untitaker quit (Ping timeout: 240 seconds) |
12:24:13 | * | untitaker joined #nimrod |
12:51:50 | * | darkf quit (Quit: Leaving) |
13:13:48 | * | rixx joined #nimrod |
13:15:56 | * | rixx quit (Read error: Connection reset by peer) |
13:16:06 | * | rixx joined #nimrod |
13:31:06 | * | Varriount-Mobile quit (Ping timeout: 264 seconds) |
13:41:59 | * | dirkk0 joined #nimrod |
13:45:42 | * | dirkk0 quit (Read error: Connection reset by peer) |
13:47:24 | * | dirkk0 joined #nimrod |
13:52:01 | * | dirkk_ joined #nimrod |
13:54:06 | * | dirkk__ joined #nimrod |
13:55:42 | * | dirkk0 quit (Ping timeout: 264 seconds) |
13:57:14 | * | dirkk_ quit (Ping timeout: 252 seconds) |
14:01:42 | * | flaviu1 joined #nimrod |
14:02:10 | * | flaviu1 is now known as Guest67360 |
14:02:49 | * | Guest67360 is now known as flaviu |
14:06:19 | NimBot | Araq/Nimrod devel 9354b8a Araq [+0 ±1 -0]: added allValues iterator |
14:06:19 | NimBot | Araq/Nimrod devel 15909c7 Araq [+0 ±7 -0]: optimized method dispatchers |
14:08:43 | * | BitPuffin quit (Ping timeout: 240 seconds) |
14:21:44 | * | dirkk0 joined #nimrod |
14:24:55 | * | dirkk__ quit (Ping timeout: 272 seconds) |
14:27:50 | * | askatasuna joined #nimrod |
14:29:04 | * | Varriount-Mobile joined #nimrod |
14:29:29 | * | Varriount-Mobile quit (Remote host closed the connection) |
14:29:44 | * | Varriount-Mobile joined #nimrod |
14:30:06 | * | Varriount-Mobile quit (Remote host closed the connection) |
14:30:24 | * | Varriount-Mobile joined #nimrod |
14:35:26 | araq | Varriount-Mobile: [windows-x86_64 15909c7be25a devel] Testing failed: "koch.exe tests" failed |
14:35:30 | araq | please have a look |
14:36:09 | NimBot | Araq/Nimrod devel d3c8f1a Araq [+0 ±1 -0]: fixes recently introduced regression |
14:39:22 | NimBot | Araq/Nimrod devel 6975e77 Grzegorz Adam Hankiewicz [+0 ±1 -0]: Adds docstring example to system.fieldPairs. |
14:39:22 | NimBot | Araq/Nimrod devel 7da3c5e Grzegorz Adam Hankiewicz [+0 ±1 -0]: Adds do notation example to algorithm.sort. |
14:39:22 | NimBot | Araq/Nimrod devel 9009841 Grzegorz Adam Hankiewicz [+0 ±1 -0]: Avoids temporal string in tables hashing example. |
14:39:22 | NimBot | Araq/Nimrod devel bde9d1a Grzegorz Adam Hankiewicz [+0 ±1 -0]: Adds to tables module example of reference type vs value type. |
14:39:22 | NimBot | 4 more commits. |
14:40:02 | * | kunev quit (Quit: leaving) |
14:41:41 | araq | zahary: https://github.com/Araq/Nimrod/pull/1184 please pull or reject with explanations |
14:47:46 | EXetoC | what's allValues for? don't tables describe one-to-one relationships? |
14:48:02 | araq | 'add' allows one-to-many |
14:48:12 | araq | '[]=' enforces one-to-one |
14:50:08 | EXetoC | oh |
14:51:48 | araq | hash conflict resolution always deals with one-to-many implicitly so once again the "best practice" is wrong :P |
14:53:51 | EXetoC | ok |
14:54:05 | EXetoC | chcks? such miniscule shortenings :p |
14:56:49 | araq | that was done to prevent some conflict I can't remember |
14:57:15 | araq | but yeah, we need a renamefest |
14:58:59 | EXetoC | fair enough |
15:01:01 | * | bjz quit (Ping timeout: 272 seconds) |
15:03:01 | EXetoC | that's used elsewhere though, but that can be renamed too. not sure if serious though, but we're still at < 1.0 |
15:04:44 | * | dirkk0 quit (Quit: This computer has gone to sleep) |
15:09:43 | * | freezerburnv joined #nimrod |
15:16:26 | * | dirkk0 joined #nimrod |
15:24:53 | * | dirkk0 quit (Ping timeout: 264 seconds) |
15:29:00 | * | dirkk0 joined #nimrod |
15:38:40 | * | dirkk_ joined #nimrod |
15:39:42 | * | BitPuffin joined #nimrod |
15:40:17 | * | dirkk0 quit (Ping timeout: 272 seconds) |
15:40:46 | * | Varriount-Mobile quit (Remote host closed the connection) |
15:44:19 | * | BitPuffin quit (Ping timeout: 240 seconds) |
15:45:12 | * | dirkk_ quit (Ping timeout: 245 seconds) |
15:45:36 | * | dirkk0 joined #nimrod |
15:55:01 | * | BitPuffin joined #nimrod |
15:59:40 | * | BitPuffin quit (Ping timeout: 240 seconds) |
16:01:09 | * | dirkk0 quit (Read error: Connection reset by peer) |
16:01:45 | * | dirkk0 joined #nimrod |
16:08:10 | * | dirkk0 quit (Ping timeout: 240 seconds) |
16:22:55 | * | hoverbear joined #nimrod |
16:39:26 | * | flaviu quit (Quit: Leaving.) |
16:39:35 | * | flaviu joined #nimrod |
17:04:36 | * | q66 joined #nimrod |
17:04:36 | * | q66 quit (Changing host) |
17:04:36 | * | q66 joined #nimrod |
17:34:39 | * | gsingh93_ joined #nimrod |
17:42:51 | * | xtagon joined #nimrod |
17:45:29 | flyx | hi folks! I didn't have time for nimrod for quite some time, now I'm on it again |
17:46:10 | flyx | why isn't TRune an ordinal type? it derives from int, so it should, right? the compiler doesn't let me declare a set[TRune] |
17:48:31 | * | DAddYE joined #nimrod |
17:48:34 | flyx | by the way, is the guy who gives a talk about nimrod next week at the GPN14 around? |
17:50:59 | * | Jehan_ joined #nimrod |
17:52:05 | dom96 | flyx: likely because it's a distinct int. |
17:52:23 | dom96 | flyx: I think that may be def-. |
17:52:25 | dom96 | brb |
17:52:36 | flaviu | Its def- |
17:54:05 | * | Jesin quit (Quit: Leaving) |
17:54:28 | * | Jesin joined #nimrod |
17:54:33 | flyx | hm, right, distinct probably removes the necessary stuff from the type |
17:55:29 | Jehan_ | flyx: Yes. `distinct` creates a new type with the same layout, but without any of the procedures and methods associated with the old one. |
17:56:12 | Jehan_ | What are you using `distinct` for? |
17:56:27 | Jehan_ | You can use borrowing to incorporate existing procedures, for what it's worth. |
17:56:29 | flyx | TRune is in the standard library. |
17:56:52 | Jehan_ | Ah, I must have missed the context. |
17:57:00 | flyx | it's in the unicode module |
17:57:13 | araq | set[int] is not valid either fwiw |
17:57:44 | araq | you need to use TSet[int] and that's a hash set that works with TRune too once you give a 'hash' proc for TRune |
17:58:35 | flyx | ah. what's set for then, if it doesn't even work on int? |
17:58:47 | Jehan_ | set is a bitset type. |
17:59:13 | Jehan_ | It doesn't work on int because the memory usage would make that impossible. |
17:59:29 | flyx | ah |
17:59:34 | * | askatasuna quit (Remote host closed the connection) |
17:59:47 | flaviu | Jehan_: The solution is simple: Use LLVM, it lets you have integers of any size. Who cares about using 2^32 bits of memory. :P |
18:00:27 | Jehan_ | flaviu: Not sure what integer size has to do with that? |
18:01:05 | flaviu | Use a bitset with 2^32 bits, it was a joke. Not really funny I guess |
18:01:31 | flaviu | Although that wouldn't work since llvm apparently only supports integers with up to 2^23 bits. |
18:01:54 | Jehan_ | In particular because it's still a bit large for 32-bit architectures? |
18:03:00 | Jehan_ | Mind you, it's not that I've never needed larger bit sets than size 2^16 (the maximum Nimrod allows), but it isn't hard to write them yourself, so it's not exactly a priority. |
18:03:45 | flaviu | I know, just ignore me and my bad jokes. |
18:03:50 | flaviu | :P |
18:09:50 | * | Jesin quit (Quit: Leaving) |
18:11:36 | * | dirkk0 joined #nimrod |
18:13:07 | araq | Jehan_: what's your opinion about unbounded channels? |
18:13:18 | Jehan_ | araq: In what context? |
18:13:49 | * | joelmo joined #nimrod |
18:14:13 | araq | in general as a primitive in comparison to providing only bounded channels |
18:14:38 | Jehan_ | Umm. Having only bounded channels would be bad in general. |
18:15:01 | Jehan_ | I mean, I guess some people probably love countless more opportunities for deadlock, but I'm not one of them. :) |
18:15:22 | * | askatasuna joined #nimrod |
18:16:06 | araq | well golang only has bounded channels... |
18:16:59 | Jehan_ | As a practical matter, you can of course always emulate unbounded channels with bounded ones. |
18:17:19 | Jehan_ | I mean, that's a fairly typical pattern in CSP, which technically only has synchronous, 1-element "channels". |
18:18:46 | Jehan_ | And yes, that's another way in which Go is pretty … well, broken. |
18:18:59 | Jehan_ | CSP gets away with it by having lots of things that Go doesn't have. |
18:19:26 | Jehan_ | Plus, it's really a process algebra intended to build complex processes from a few elementary processes. |
18:20:24 | Jehan_ | But even so, Go implements only a subset of CSP's constructs. |
18:21:27 | Jehan_ | Call it a watered-down, memory-unsafe Occam2 dialect if you will. |
18:25:00 | Jehan_ | Unlike with Rust, D, or Nimrod, to this day I don't really see what Go buys me over using C++ with the Boehm GC and a couple of fairly trivial libraries. |
18:28:15 | araq | well I'm reading the Rust mailing list about this topic |
18:28:36 | araq | and the arguments for having only bounded channels are not bad |
18:28:52 | Jehan_ | Guaranteed memory usage, I guess? |
18:29:34 | Jehan_ | Plus, in Rust it probably matters that you don't have to worry about reallocating queue memory because of a send. |
18:30:46 | Jehan_ | Even so, I don't see the point of excluding unbounded channels. |
18:30:49 | araq | https://www.mail-archive.com/[email protected]/msg07572.html |
18:31:37 | araq | I am in favor for unbounded channels |
18:32:09 | araq | otherwise you simply get arbitrary bounds everywhere |
18:32:24 | Jehan_ | araq: He's overlooking the deadlock potential of bounded channels, as far as I can tell. |
18:32:43 | araq | yeah well other posts have examples for easy deadlocking |
18:33:07 | Jehan_ | Remember that a one-element channel is functionally equivalent to a mutex. |
18:33:19 | Jehan_ | So, in that case, any cyclic communication can deadlock. |
18:35:14 | Jehan_ | More importantly, channels aren't a very good high-level concurrency construct. |
18:35:48 | Jehan_ | Channels make a very powerful concurrency *primitive*. But they're not very good for abstracting over concurrent behavior. |
18:36:30 | * | Jesin joined #nimrod |
18:37:15 | Jehan_ | If you have a lot of channels, then reasoning about their topology becomes very hard. |
18:37:52 | araq | I agree completely. |
18:38:43 | Jehan_ | With respect to his non-determinism argument: What you generally need to reason about with respect to boundedness is the number of channel elements that can be in transit globally. |
18:39:23 | Jehan_ | Of course, if you are, say, dealing with an embedded system, then an entirely different set of additional constraints apply. |
18:39:36 | Jehan_ | Which is also why I avoid embedded systems like the plague. :) |
18:39:55 | araq | well the argument about determinism is valid |
18:40:08 | araq | the other arguments are stupid |
18:41:02 | Jehan_ | The argument about determinism is about a toy example where, yes, a bounded buffer *can* be the better solution. |
18:41:05 | dom96 | araq: Do you mean we'll get both bounded and unbounded channels or just unbounded? |
18:41:33 | araq | dom96: for now we only have unbounded channels, I don't know what we will get |
18:41:41 | Jehan_ | dom96: In general, you want both. Both have their use cases. What I'm speaking against is not having unbounded channels at all. |
18:42:48 | dom96 | Jehan_: I agree. Which is why I ask what araq's plans are. |
18:43:48 | araq | what are the use cases for bounded channels? can't think of any (except when the size is 1 for syncronization). it's more of an optimization to be able to use fixed size arrays |
18:44:26 | Jehan_ | araq: His example would be one in that it guarantees bounded memory usage. |
18:44:49 | Jehan_ | The problem is more that it's not a real-world example, so it's hard to think up actual code that exhibits such behavior. |
18:44:51 | araq | that's not a use case, that's an external requirement |
18:46:05 | Jehan_ | Bounded buffers can also be useful with a poll/select primitive. |
18:46:52 | araq | the only language that takes "bounded memory usage" seriously is Ada anyway |
18:47:24 | Jehan_ | Heh. |
18:47:26 | araq | and Ada is painful enough that I copied it, called it Nimrod and added unbounded strings/seqs ... |
18:47:48 | Jehan_ | :) |
18:48:26 | Jehan_ | The thing that you can be concerned about is what happens if one reader stalls and a writer produces an unbounded amount of data. |
18:49:04 | Jehan_ | That's not quite the same as other "unbounded memory" solutions. |
18:49:12 | Jehan_ | It's more like a garbage collector not working. |
18:50:05 | Jehan_ | In practice, the correct solution is to prevent the reader from stalling and to make sure scheduling is fair. |
18:50:31 | Jehan_ | Admittedly, POSIX doesn't allow you to promise that, but in practice, actually existing OSs do. |
18:53:38 | Jehan_ | SCHED_OTHER infamously allows an implementation to do whatever it wants to do. And it's the default scheduling policy. |
19:01:35 | araq | speaking of which ... I searched for an option to do "yeah, I created 16 threads, all CPU bound, don't schedule them fairly, minimize thread switches instead" |
19:02:10 | araq | so the OS runs 4 at the same time when I have 4 cores and keeps the other 12 for later |
19:02:25 | araq | let's call it the "completely unfair scheduling" ;-) |
19:02:51 | * | joelmo quit (*.net *.split) |
19:02:51 | * | gsingh93_ quit (*.net *.split) |
19:02:54 | araq | does any OS support that? |
19:03:17 | * | joelmo joined #nimrod |
19:03:48 | EXetoC | so as to minimize spawns? |
19:03:53 | * | gsingh93_ joined #nimrod |
19:06:49 | Jehan_ | The problem is that you can only stuff so many scheduling strategy options in an OS API. |
19:07:05 | Jehan_ | You're usually better off writing your own scheduler. |
19:07:42 | araq | well it's a very common use case, more common than hard realtime requirements afaict |
19:07:48 | Jehan_ | Which, admittedly, has its own downside. |
19:08:12 | Jehan_ | araq: Yeah, but most of the relevant standards stuff was written decades ago when people were thinking differently. |
19:11:07 | * | DAddYE quit (Remote host closed the connection) |
19:11:41 | Jehan_ | To this day I still don't get why the ucontext functions were deprecated. |
19:11:50 | Jehan_ | They should have been expanded upon. |
19:12:54 | * | Matthias247 joined #nimrod |
19:15:09 | araq | I mean seriously... how hard is it to come up with it? execProcesses does exactly that, cause it doesn't make sense to start cmds.len processes all fighting for a cpu just because you know you can execute them all in parallel |
19:16:01 | araq | but no, instead the OS tries to be fair ... |
19:17:14 | Jehan_ | Because the OS can't predict what they will do in the future. |
19:17:31 | araq | yes, hence I should be able to tell the OS |
19:17:41 | Jehan_ | In all fairness, if they're all CPU bound, you'll have context switches only at time slice intervals, which isn't bad. |
19:18:28 | araq | I'm not sure about that |
19:18:58 | Jehan_ | Should be, at least on any sane OS. :) |
19:19:46 | Jehan_ | I'm assuming here that there are no other processes involved that can mess up scheduling. |
19:20:57 | def- | flyx: hi |
19:21:37 | fowl | araq, you'd rather have compile-time coverage of the stuff in the os module than working ffi, which would make the repl more useful |
19:21:44 | * | DAddYE joined #nimrod |
19:21:57 | fowl | :< |
19:23:07 | flyx | def-: hi! just wanted if you already have a plan what your talk will cover. I'll probably be attending ;) |
19:23:24 | * | kunev joined #nimrod |
19:24:30 | * | Demos joined #nimrod |
19:24:42 | def- | flyx: I started working on the talk yesterday. not sure yet on how much i can include |
19:25:46 | Matthias247 | araq: you could just avoid the processes, but all things as tasks into one process and do your own scheduling ;) |
19:25:48 | flyx | well, a friend of mine once did a talk on Python and could hardly cover the basics in one and a half hour. |
19:26:13 | araq | Matthias247: that's what I'm doing, more or less. but I like to complain. |
19:26:32 | def- | flyx: i think i should get some interesting examples and explain based on them |
19:26:38 | Matthias247 | araq: ah ok ;) |
19:26:51 | Matthias247 | i like that too ;) |
19:27:25 | Demos | def-: someone was working on an import macro that worked like go's thing, where you can import a repo from github. I forget who it was though |
19:27:31 | flyx | def-: yeah that would probably be the best. I figure people wouldn't be much surprised if another programming language allows one to code loops… |
19:27:55 | EXetoC | Demos: the one mentioned a couple of minutes ago? :> |
19:28:04 | EXetoC | oh |
19:28:04 | Demos | oh maybe, I just joined |
19:28:10 | EXetoC | yeah |
19:28:18 | def- | Demos: import_repo, i saw that a few days ago here |
19:28:25 | EXetoC | and that was in the offtopic channel |
19:28:31 | EXetoC | silly fowl! |
19:34:49 | * | DAddYE quit (Remote host closed the connection) |
19:45:20 | * | NimBot joined #nimrod |
19:49:45 | * | DAddYE joined #nimrod |
19:50:03 | EXetoC | NimBot: 123 |
19:51:18 | def- | Jehan_: Yes, that's what we were talking about |
20:20:59 | flyx | how can I test if a TSet is initialized? |
20:26:00 | dom96 | hrm, I don't think you can. |
20:26:42 | dom96 | TSet should possibly be a ref |
20:27:20 | araq | initSet[int]() |
20:28:18 | araq | oh you mean *test* for initialization? that's not really supported, i think |
20:31:24 | * | superfunc_ joined #nimrod |
20:33:13 | Jehan_ | I should probably do for sets.nim what I did for tables.nim and provide a reference version. |
20:33:38 | araq | no, please don't |
20:33:44 | Jehan_ | No? |
20:34:04 | araq | I added an allValues iterator for the TTable but couldn't be bothered with the PTable version |
20:34:18 | araq | auto deref solves that problem for the most part |
20:34:28 | superfunc_ | Araq: I have a question if you don't mind. |
20:34:42 | araq | go ahead |
20:34:51 | Jehan_ | Hmm. auto deref wasn't really doing enough for me, which is why I did it in the first place. |
20:35:17 | araq | Jehan_: well yes, more auto deref is planned |
20:35:32 | Jehan_ | I see. Yeah, that would mostly fix it, too. |
20:35:41 | araq | let's implement that instead of doing T/P everywhere |
20:36:08 | superfunc_ | I'm tying up things in my library, and a colleague brought up an interesting question. Is it worthwhile to re-implement the data structures with manual memory management or let the GC take care of it? The GC penalty is very low in nimrod, so I think even in games it would be usable(and more maintainable), but I was wondering what you though |
20:36:10 | superfunc_ | t |
20:37:09 | Jehan_ | Araq: I'm fine with that. |
20:37:16 | araq | indeed I don't think it's worth while, superfunc_ |
20:37:31 | superfunc_ | I figured as much, just thought I'd confirm |
20:37:47 | superfunc_ | This way it will align with the semantic decisions of the stdlib of nimrod |
20:39:35 | * | DAddYE quit () |
20:40:07 | araq | 'new' already can end up being more efficient than 'malloc' since it's threadlocal in nimrod |
20:40:22 | Demos | for stuff like vectors (strechy arrays) just let the GC do it because it is just not worth the hassle. For tree structures the GC makes everything much less painful for little cost |
20:40:39 | Jehan_ | araq: Well, a thread-local malloc would have the same benefit. :) |
20:42:00 | araq | Jehan_: yes but usually people don't bother |
20:42:38 | araq | somebody should test my improved method dispatching... I'm curious |
20:43:01 | Jehan_ | araq: tcmalloc? |
20:46:12 | Jehan_ | Is it on devel? I may give it a whirl. |
20:46:19 | araq | yup |
20:46:41 | araq | it implements the discussed improvements |
20:46:56 | araq | but the linear search still exists |
20:47:34 | araq | I don't know if that really is a problem in practice |
20:47:56 | araq | when you use subtyping excessively instead of a case object, you're doing it wrong :P |
20:49:16 | * | hoverbea_ joined #nimrod |
20:49:44 | Jehan_ | Eh, it may simply mean that all subtypes cannot be contained in a single module. |
20:50:54 | araq | yes. happens very rarely in my experience |
20:51:15 | araq | unless you're writing a traditional OO based UI library, perhaps |
20:51:43 | Jehan_ | araq: Types that you want users of a module to be able to extend. |
20:52:10 | araq | yeah, I heard about these mystical types |
20:52:42 | * | hoverbear quit (Ping timeout: 245 seconds) |
20:54:02 | Jehan_ | Happens in computer algebra all the time, actually. |
20:54:24 | Jehan_ | I suspect that it's both domain-specific and how you write software. |
20:56:15 | Jehan_ | OCaml also has polymorphic variants in addition to its normal variants for largely such reasons. |
20:56:23 | * | Kazimuth joined #nimrod |
20:56:31 | Demos | if you do not subtypes to be outside of a given module why on earth are you using methods in the first place? |
20:57:09 | araq | Jehan_: and "everybody" says to not use that part of Ocaml |
20:57:25 | Jehan_ | araq: Hmm, everyone says not to use the "objects" part of OCaml. |
20:57:47 | Jehan_ | Not that polymorphic variants don't have their problems, but they do address an actual need. |
21:00:25 | Jehan_ | You can do open-ended polymorphism with a record of closures, too, but there you have the problem of overhead. |
21:01:03 | Jehan_ | In that every instance of a class, and not just the class itself, carries a dispatch table around. |
21:02:44 | araq | there is little point in telling me things I already know. :P |
21:04:54 | Jehan_ | Well, you said that it happens rarely in your experience. :) |
21:08:02 | Jehan_ | Hmm, the dispatch code looks odd. I think I need to understand what's going on in there first. |
21:10:21 | araq | well it passes all the tests :P |
21:11:28 | * | kunev quit (Quit: leaving) |
21:11:41 | Jehan_ | Oh, I wasn't doubting that it was correct. |
21:11:45 | reactormonk | araq, make up your mind on #1130 |
21:11:56 | Jehan_ | I was simply trying to understand the logic behind it. |
21:13:59 | araq | well in fact, it incorrectly generates & instead of && |
21:14:12 | araq | but this is an old bug that happens to not affect correctness |
21:14:27 | * | joelmo quit (Quit: Connection closed for inactivity) |
21:16:34 | araq | Jehan_: reordering the checks in isObjWithCache() might speed things up |
21:17:17 | araq | in particular checking for cache[0] == obj firstly or secondly |
21:18:08 | * | freezerburnv quit (Quit: freezerburnv) |
21:18:35 | Jehan_ | It's interesting, the overhead is less horrible than I expected. |
21:19:19 | Jehan_ | For having 100 subclasses. |
21:20:08 | Jehan_ | Dispatching on the first alternative: .7s, on the 50th: 1.7s, on the 100th: 3.0s. |
21:21:00 | Jehan_ | Fun aside: The software system I'm working on right now (not my creation) does variable lookup using a linear search. |
21:21:12 | Jehan_ | It does that each time the variable is used, not just when the code is compiled. |
21:21:27 | Jehan_ | I was amazed to find that it doesn't completely kill performance. |
21:21:41 | Jehan_ | Admittedly, part of the reason is that local variables are at the front of the list. |
21:23:22 | araq | well you should compare it with the nimrod version that's not devel |
21:23:29 | araq | *with a |
21:24:32 | Jehan_ | I will in a moment. |
21:24:51 | Jehan_ | I first had to write a program to generate that type structure and methods to go with it. |
21:25:06 | Jehan_ | One thing I'd consider is to have a per-method one entry cache. |
21:25:18 | Jehan_ | Which basically stores the last alternative that was tried. |
21:25:34 | Jehan_ | And the next time checks that first. |
21:25:55 | araq | that's a classic cache yes |
21:25:56 | Jehan_ | Hmm, wait, that's difficult to do in C. |
21:26:28 | Jehan_ | At least without changing what the dispatch code looks like. |
21:26:55 | araq | it's difficult to do efficiently |
21:27:50 | Jehan_ | Well, I can tell you right now that the old version is a LOT slower for 100 subtypes. |
21:27:57 | Jehan_ | Ah, yes, 39 seconds. |
21:28:35 | Jehan_ | For the 100th case. And 7 seconds for the first. |
21:28:40 | Jehan_ | So, about a 10x speedup. |
21:28:57 | Jehan_ | One benchmark, of course, and a fairly trivial one. |
21:29:17 | Jehan_ | So nothing that I'd generalize. |
21:29:33 | araq | well it tests the worst case |
21:29:48 | araq | the other cases should be better |
21:29:59 | Jehan_ | Well, the 7 second case is one where the first alternative is a success. |
21:29:59 | araq | and the speedup comparable, but that's just a guess |
21:30:25 | Jehan_ | .7 vs 7 seconds for where the first check in the dispatch logic succeeds. |
21:30:53 | araq | reactormonk: I told you to not to do the moveMem stuff, not sure what happend with my comment on github |
21:31:16 | araq | also reactormonk complained it's wrong and you never answered him |
21:31:20 | araq | er |
21:31:26 | araq | EXetoC complained |
21:33:19 | reactormonk | which question? |
21:33:46 | araq | Jehan_: the problem with a classic cache is that it re-introduces the indirect call which I was after to avoid in the first place |
21:34:10 | araq | which is also very fast on x86 these days ... |
21:34:23 | Jehan_ | which indirect call that you wanted to avoid? |
21:34:39 | araq | any kind of indirect call in the dispatching |
21:36:06 | EXetoC | I only remember asking where my proposed changes to the offsets went |
21:36:41 | EXetoC | then I asked if maybe the problem was solved in some other way. I don't think I got an answer (breaking instead of breaking+1 etc) |
21:37:11 | Jehan_ | araq: Because it doesn't work well with branch prediction on some processors, especially older ones? |
21:37:56 | araq | exactly, it was a full pipeline flush |
21:38:33 | Jehan_ | araq: Yeah, that was a big reason why SmallEiffel did so well using a case statement back then. :) |
21:38:42 | Jehan_ | And why I copied SmallEiffel's approach. :) |
21:39:53 | araq | I think prediction still sucks and it always predicts the last known jump target |
21:40:20 | Jehan_ | It's actually a bit more sophisticated these years. |
21:40:24 | Jehan_ | At least on x86. |
21:40:32 | Jehan_ | Well, maybe not for indirect calls. |
21:41:09 | Jehan_ | I did read a write-up on how branch prediction works now about three years ago. |
21:41:16 | Jehan_ | Well, how it worked three years ago. :) |
21:41:53 | araq | branch prediction is quite different from jump *target* prediction though |
21:44:42 | araq | btw the linear dispatching that we do is very similiar to what's done with C++ VTables on a GPU :-) |
21:45:09 | Jehan_ | The downside of a switch statement, by the way, is that it uses a lot of slots in the branch prediction table. |
21:45:31 | araq | which don't support indirect calls at all, so you don't have a choice |
21:46:20 | Demos | putting c++ vtbls on the GPU seems like somewhat of a waste of time to me |
21:46:36 | Demos | who is doing it? |
21:46:43 | araq | Demos: nvidia |
21:46:54 | Jehan_ | Also, http://www.agner.org/optimize/#manuals |
21:47:06 | Demos | for the D3D11 interface stuff? |
21:47:13 | Jehan_ | Always a good resource for code optimization. |
21:47:26 | araq | Demos: for compiling C++ to GPU |
21:47:42 | Demos | OK that is pretty cool |
21:47:52 | Demos | I thought they just did a subset of C |
21:48:22 | Demos | also http://www.intel.com/content/www/us/en/architecture-and-technology/64-ia-32-architectures-optimization-manual.html |
21:52:40 | Jehan_ | Demos: Yes, I know that. |
21:54:06 | * | askatasuna quit (Quit: WeeChat 0.4.3) |
21:54:24 | Demos | well I knew about agner's optimization resources :D |
21:54:56 | araq | we all know everything :-) |
21:54:58 | Jehan_ | Demos: Wasn't specifically intended for you. :) |
21:55:22 | Demos | Jehan_: well mine was not intended specifically for you :> |
21:55:34 | Jehan_ | :) |
21:59:02 | araq | Jehan_: if the 100 classes are all leaves you merely test another optimization and not the new caches |
21:59:47 | araq | the compiler annotates leaf objects as final and generates a much more efficient 'of' check |
21:59:51 | Jehan_ | araq: Yes, but that's a common case. |
22:00:16 | Jehan_ | Deep inheritance hierarchies rarely make sense. |
22:00:16 | araq | true but then maybe we shouldn't bother with the caches |
22:00:44 | Jehan_ | Doesn't mean that other cases don't happen. |
22:03:53 | araq | my white-/blacklist cache for object type checking might be novel. any idea if that's the case? |
22:04:14 | Jehan_ | No idea, to be honest. |
22:04:46 | Jehan_ | Hmm, it looks like AMD at least can handle more than two branch prediction targets for indirect jumps these days. |
22:05:16 | araq | how do they do it? |
22:05:51 | Jehan_ | No information that I can find. |
22:05:59 | araq | what do they use as dependency? |
22:11:16 | araq | "The AVX512 instruction set uses a new 4-bytes prefix named EVEX" ... |
22:11:24 | araq | yay a 4-byte prefix |
22:11:31 | araq | and more than 100 new instructions |
22:11:38 | Jehan_ | If I had to do it, I'd probably use a history-based approach. |
22:12:05 | Jehan_ | Or at least start with one. |
22:12:09 | araq | Jehan_: history based on what? |
22:12:18 | Jehan_ | History based on previous jump targets. |
22:12:30 | araq | lol obviously |
22:12:42 | araq | ok, so eax contained 3 different jump targets |
22:12:52 | araq | which one do you predict? |
22:13:03 | Jehan_ | Which address I jumped to before. |
22:13:09 | flaviu | araq: AMD apparently copies Intel's mechanism for predicting indirect branches |
22:13:19 | Jehan_ | Eh, that was unclear. |
22:13:22 | flaviu | http://www.agner.org/optimize/microarchitecture.pdf |
22:13:35 | flaviu | p197, last paragraph |
22:14:24 | araq | Jehan_: yes but then why do you even keep the last 3 different addresses? |
22:14:27 | Jehan_ | I mean, if I jumped to A, then B, then A, then I'd predict B. |
22:14:58 | Jehan_ | I'd keep pairs (T1, T2). If the previous target was T1, I'd predict T2. |
22:15:16 | araq | sounds very risky, but ok |
22:15:31 | Jehan_ | araq: Agreed. |
22:15:43 | Jehan_ | I'd have to look at what the history in typical code actually looks like. |
22:15:58 | Jehan_ | I would suspect that indirect jumps are either monomorphic or fairly random. |
22:19:49 | Jehan_ | I have to say, what the Mill guys do looks pretty interesting in that regard. |
22:23:37 | araq | the Mill is pretty interesting in every regard :-) |
22:23:52 | araq | or perhaps it's only really good marketing |
22:26:00 | EXetoC | have you watched any of the presentations? |
22:26:21 | flaviu | I don't think that Gandalf giving lectures is particularly good marketing, I think its because the claims sound doable at this moment in time. |
22:29:57 | * | Demos quit (Quit: leaving) |
22:32:11 | araq | EXetoC: yes, I watched 2 or 3 |
22:32:52 | araq | flaviu: marketing doesn't have to be a shiny commercial video |
22:33:36 | flaviu | Well, marketing in this case isn't much more than making a few lectures, and occasionally posting them to hackernews and reddit |
22:34:00 | araq | good marketing for engineers might be "Gandalf giving lectures" |
22:35:02 | EXetoC | so, good but deceptive marketing spanning several hours? who knows |
22:35:09 | EXetoC | might fool a nub like me |
22:35:21 | flaviu | Or "A new CPU architecture that offloads the complicated decisions to the compiler so it can focus on actually doing work" |
22:36:40 | flaviu | EXetoC: Maybe, but I haven't seen any major criticisms of it |
22:37:51 | * | dirkk0 quit (Quit: This computer has gone to sleep) |
22:38:19 | EXetoC | more control for compilers? sounds good on paper at least |
22:51:46 | Matthias247 | good marketing for me would only be running $shooter_xyz and posting benchmark numbers ;) |
22:51:58 | araq | "Branch prediction in Intel Haswell" |
22:52:12 | araq | "Pattern recognition for indirect jumps and calls --- |
22:52:14 | araq | Indirect jumps and indirect calls are predicted well. " |
22:52:19 | araq | good to know lol |
22:52:27 | Matthias247 | there were already some architectures which looked good on paper and performed really bad in practice |
22:52:28 | EXetoC | NimBot: can you do any tricks? |
22:52:35 | araq | !lag |
22:52:35 | NimBot | 36ms between me and the server. |
22:53:15 | flaviu | Matthias247: Apparently looks good in simulation too |
22:53:40 | flaviu | !help |
22:53:44 | EXetoC | who knows then |
22:53:57 | flaviu | !lastseen aboutgod |
22:54:00 | Jehan_ | The one problem I see with the Mill architecture is that instruction latency is part of the instruction semantics. |
22:54:44 | Jehan_ | I.e. if you make instructions faster, then you can't benefit from that. |
22:55:40 | reactormonk | araq, so no memmove at all. Ok. |
22:57:32 | dom96 | flaviu: it's !seen |
22:58:19 | flaviu | !ping |
22:58:19 | NimBot | pong |
22:58:19 | flaviu | !repos |
22:58:19 | NimBot | Announced repos: Araq/Nimrod, nimrod-code/nimbuild, nimrod-code/aporia, nimrod-code/nimforum, nimrod-code/babel, nimrod-code/packages, dom96/jester, nimrod-code/csources, Varriount/Nimrod-Sublime, Varriount/NimLime, nimrod-code/opencl |
22:58:24 | araq | Jehan_: it's abstracted away via a JIT I think |
22:59:05 | EXetoC | !ping |
22:59:05 | NimBot | pong |
22:59:06 | Jehan_ | araq: Ah, so you don't generate code for the architecture directly, but an intermediate code that is then compiled? |
22:59:07 | EXetoC | !ping |
22:59:07 | NimBot | pong |
22:59:23 | Jehan_ | That would make sense. |
23:00:53 | araq | yes |
23:01:25 | EXetoC | !ping |
23:01:25 | NimBot | pong |
23:01:50 | araq | reactormonk: just add .0 for integers, not for 1e9, keep in mind this is performance critical |
23:02:02 | flaviu | Jehan_: http://millcomputing.com/docs/specification/ |
23:02:21 | flaviu | The youtube thumbnail I think explains it well. |
23:06:03 | * | Araq_ joined #nimrod |
23:06:06 | Araq_ | !addtrust |
23:06:06 | NimBot | Syntax: !addtrust <nick> <host> |
23:06:10 | Araq_ | !addtrust me |
23:06:10 | NimBot | Syntax: !addtrust <nick> <host> |
23:06:17 | Araq_ | !addtrust me asd |
23:06:17 | NimBot | Access denied. |
23:06:23 | * | Araq_ quit (Client Quit) |
23:06:35 | araq | fraud! |
23:06:45 | araq | I'm the only araq in town |
23:12:41 | * | Matthias247 quit (Read error: Connection reset by peer) |
23:16:51 | * | io2 quit (Quit: ...take irc away, what are you? genius, billionaire, playboy, philanthropist) |
23:19:29 | araq | good night |
23:19:41 | * | darkf joined #nimrod |
23:21:00 | flaviu | !kirbyrape |
23:21:00 | NimBot | (>^(>O_O)> |
23:21:30 | * | hoverbea_ quit () |
23:23:51 | * | Jehan_ quit (Quit: Leaving) |
23:40:48 | reactormonk | araq, ok |
23:43:04 | reactormonk | any locale that uses "." as thousand-separators? |
23:43:29 | * | reactormonk is now known as reactormonk_ |
23:51:30 | * | nande joined #nimrod |