Skip to contentSkip to conversation

some questions using rdtsc in user space

DISCUSSION Alexandre P. Nunes 2 participants 3 messages Aug 2, 2002 – Aug 3, 2002 1 message not in the archive

lore
Share & tools
lore
#0 lore raw

Hi,

Both I and a friend have with an interesting scenario, maybe someone can help us.

We have to access a device connected to parallel port, which works in the following way: you send a byte to the port, to turn some bits on (reflecting on some pins on the parallel port), which is interpreted by the device as a command. Then you are supposed to sleep about ~200ns (maybe more, just can't be much less), and then you send a byte which is received by the device as data, pertinent to command.

We wrote a program which accomplishes this by doing outb() to appropriate address(es), followed by usleep(1), but that seems to take about 10 ms at average or so, which is far from good for our application.

I read somewhere that putting the process in real-time priority could lead the average to 2ms, but I had this though that I could solve this by using rdtsc instruction, because as far as I know it won't cause a trap to kernel mode, which maybe expensive, am I right?

I don't have the need to use real time linux (though I'm considering real-time priority), nor desperate time precision needs, what I don't want is to have huge delays. I cannot relay on the low-latency patches too, if possible (though I know it could help), because the program will eventually run on standard kernels.

If using rdtsc is a good way, someone knows how do I do some sort of loop, converting the rdtsc difference (is it in cpu clocks, right?) to nano/microseconds, and if there could be bad behaviour from this (I believe there could be some SMP issues, but for now this is irrelavant for us).

Thanks!

Alexandre

P.S..: carbon-copy me, since I'm not subscribed to the list.

A message that is not in the archive (sent off-list or not yet received): [email protected]

#2 lore raw
Quoted 10 lines · Chris Friesen

[snip]

Quoted 7 lines

If using rdtsc is a good way, someone knows how do I do some sort of loop, converting the rdtsc difference (is it in cpu clocks, right?) to nano/microseconds, and if there could be bad behaviour from this (I believe there could be some SMP issues, but for now this is irrelavant for us).

Quoted 4 lines

You'd be more portable looping on gettimeofday(), which returns back seconds and microseconds. The disadvantage is that if you change the system time while your program is running you can get screwed.

I guess ntpd would be the evil on this issue, because at least in some machines I have here, it makes minor (sometimes not "that" minor) corrections every half hour or so...

Quoted 10 lines

If you want to loop on rdtsc (which as you say is often clockspeed, but that is not necessarily exactly what is advertised), then the first thing you need to do is to figure out how fast you're going. What I usually do is grab a timestamp, sleep for 10 seconds using select(), and grab another timestamp. Figure out the difference in timestamps, divide by 10, and you get ticks/sec. If it's close to your advertised clock rate, then round it up to the clock rate for ease of calculation. As an example, my 550MHz P3 gives 548629000 ticks/sec using this method, so for your purposes I'd round it up to 550000000.

Quoted 5 lines

Once you have this information, just divide by 5 million to get the number of ticks in 200ns.

Ok, that's exactly where I was trying to get to, I'll do some experiments, thank you!

Alexandre

#3 lore raw
In reply to Alexandre P. Nunes

Have you just tried spinning in a tight loop using gettimeofday to get the time? It's not exactly efficient, but if you need that kind (200ns) of precision that is about the only way. You'll still be stuck with 1usec precision since that is as good as gettimeofday can do, but that's a far sight better than 10ms or even 2ms.

Ben

Quoted 28 lines · Alexandre P. Nunes

Hi,

Both I and a friend have with an interesting scenario, maybe someone can help us.

We have to access a device connected to parallel port, which works in the following way: you send a byte to the port, to turn some bits on (reflecting on some pins on the parallel port), which is interpreted by the device as a command. Then you are supposed to sleep about ~200ns (maybe more, just can't be much less), and then you send a byte which is received by the device as data, pertinent to command.

We wrote a program which accomplishes this by doing outb() to appropriate address(es), followed by usleep(1), but that seems to take about 10 ms at average or so, which is far from good for our application.

I read somewhere that putting the process in real-time priority could lead the average to 2ms, but I had this though that I could solve this by using rdtsc instruction, because as far as I know it won't cause a trap to kernel mode, which maybe expensive, am I right?

I don't have the need to use real time linux (though I'm considering real-time priority), nor desperate time precision needs, what I don't want is to have huge delays. I cannot relay on the low-latency patches too, if possible (though I know it could help), because the program will eventually run on standard kernels.

If using rdtsc is a good way, someone knows how do I do some sort of loop, converting the rdtsc difference (is it in cpu clocks, right?) to nano/microseconds, and if there could be bad behaviour from this (I believe there could be some SMP issues, but for now this is irrelavant for us).

Thanks!

Alexandre

P.S..: carbon-copy me, since I'm not subscribed to the list.

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/

Signature · 3 lines
Ben Greear <[email protected]>       <Ben_Greear AT excite.com>
President of Candela Technologies Inc      http://www.candelatech.com
ScryMUD:  http://scry.wanfear.com     http://scry.wanfear.com/~greear