Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RISC-V support in cycleclock::Now #833

Merged
merged 1 commit into from
Jul 5, 2019
Merged

Add RISC-V support in cycleclock::Now #833

merged 1 commit into from
Jul 5, 2019

Conversation

lenary
Copy link
Contributor

@lenary lenary commented Jul 2, 2019

The RISC-V implementation of cycleclock::Now uses the user-space
rdcycle instruction to query how many cycles have happened since the
core started.

The only complexity here is on 32-bit RISC-V, where rdcycle can only
read the lower 32 bits of the 64-bit hardware counter. In this case,
rdcycleh reads the higher 32 bits of the counter. We match the powerpc
implementation to detect and correct for overflow in the high bits.

The RISC-V implementation of `cycleclock::Now` uses the user-space
`rdcycle` instruction to query how many cycles have happened since the
core started.

The only complexity here is on 32-bit RISC-V, where `rdcycle` can only
read the lower 32 bits of the 64-bit hardware counter. In this case,
`rdcycleh` reads the higher 32 bits of the counter. We match the powerpc
implementation to detect and correct for overflow in the high bits.
@googlebot
Copy link

Thanks for your pull request. It looks like this may be your first contribution to a Google open source project (if not, look below for help). Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

📝 Please visit https://cla.developers.google.com/ to sign.

Once you've signed (or fixed any issues), please reply here (e.g. I signed it!) and we'll verify it.


What to do if you already signed the CLA

Individual signers
Corporate signers

ℹ️ Googlers: Go here for more info.

@@ -164,6 +164,21 @@ inline BENCHMARK_ALWAYS_INLINE int64_t Now() {
uint64_t tsc;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not directly related to this patch, but this preprocessor hell is such a maze :/
This needs refactoring into separate functions.

@coveralls
Copy link

Coverage Status

Coverage remained the same at 91.74% when pulling 03ec6d8 on lenary:lenary/riscv-timer into 04a9343 on google:master.

asm("rdcycle %0" : "=r"(cycles_lo));
asm("rdcycleh %0" : "=r"(cycles_hi1));
// This matches the PowerPC overflow detection, above
cycles_lo &= -static_cast<int64_t>(cycles_hi0 == cycles_hi1);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now i'm curious, why is this different from the compiler lowering for READCYCLECOUNTER?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hack matches the powerpc implementation higher in the file.

As far as @asb and I can tell, this clears all the low bits if the upper bits changed between the two reads, which will be approximately correct (you know when the upper bits changed, you overflowed, and the lower bits passed through zero). This avoids branching and looping, which might cause your cycle count to change more than this hack. Both the loop and this hack compromise accuracy, it's not clear which compromises it less, but at least the hack executes in constant time regardless of overflow.

In the LLVM patch, I again copied the PPC lowering, which does use a loop, because that's what people will be expecting, and you know the returned low word is a bit pattern that was present in the cycle CSR (which you don't know with the hack, think of rdcycle taking two cycles and starting on an UINT32_MAX).

@LebedevRI
Copy link
Collaborator

Looks ok but the CLA issue needs to be resolved.

@lenary
Copy link
Contributor Author

lenary commented Jul 3, 2019

Yeah, it's going through the bureaucracy at work as we speak. Updates when I hear something.

@asb
Copy link

asb commented Jul 4, 2019

Yeah, it's going through the bureaucracy at work as we speak. Updates when I hear something.

Reluctant bureaucrat checking in :) I've docusigned the corporate CLA on behalf of lowRISC CIC, I think I now need to await a counter-signed version and perhaps explicitly list contributors afterwards.

@lenary
Copy link
Contributor Author

lenary commented Jul 5, 2019

I signed it!

@googlebot
Copy link

CLAs look good, thanks!

ℹ️ Googlers: Go here for more info.

@googlebot googlebot added cla: yes and removed cla: no labels Jul 5, 2019
@dmah42 dmah42 merged commit 4abdfbb into google:master Jul 5, 2019
@dmah42
Copy link
Member

dmah42 commented Jul 5, 2019

thank you!

llvm-git-migration pushed a commit to llvm/llvm-test-suite that referenced this pull request Jul 10, 2019
Summary:
Fixed by backporting the upstream fix from here:
  google/benchmark#833

Reviewers: lebedev.ri

Reviewed By: lebedev.ri

Subscribers: asb, kito-cheng, shiva0217, rogfer01, rkruppe, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D64237

llvm-svn: 365610
dtzWill pushed a commit to llvm-mirror/test-suite that referenced this pull request Jul 11, 2019
Summary:
Fixed by backporting the upstream fix from here:
  google/benchmark#833

Reviewers: lebedev.ri

Reviewed By: lebedev.ri

Subscribers: asb, kito-cheng, shiva0217, rogfer01, rkruppe, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D64237

git-svn-id: https://llvm.org/svn/llvm-project/test-suite/trunk@365610 91177308-0d34-0410-b5e6-96231b3b80d8
JBakamovic pushed a commit to JBakamovic/benchmark that referenced this pull request Sep 11, 2020
The RISC-V implementation of `cycleclock::Now` uses the user-space
`rdcycle` instruction to query how many cycles have happened since the
core started.

The only complexity here is on 32-bit RISC-V, where `rdcycle` can only
read the lower 32 bits of the 64-bit hardware counter. In this case,
`rdcycleh` reads the higher 32 bits of the counter. We match the powerpc
implementation to detect and correct for overflow in the high bits.
alexfanqi added a commit to alexfanqi/server that referenced this pull request Jan 5, 2022
alexfanqi added a commit to alexfanqi/server that referenced this pull request Jan 5, 2022
grooverdan pushed a commit to alexfanqi/server that referenced this pull request Jan 5, 2022
Adapted from google/benchmark#833
authored by Sam Elliot at lowRISC.

This requires the RISCV kernel to set the CY bit of the mcountern register
which is done on Linux, but documenting here in case another OS hits
a SIGILL here.

When CY bit of the mcounteren register is unset, reading the cycle register
will cause illegal instruction exception in the next privilege level ( user
mode or supervisor mode ). See the privileged isa manual section 3.1.11 in
https://github.com/riscv/riscv-isa-manual/releases/latest
grooverdan pushed a commit to MariaDB/server that referenced this pull request Jan 5, 2022
Adapted from google/benchmark#833
authored by Sam Elliot at lowRISC.

This requires the RISCV kernel to set the CY bit of the mcountern register
which is done on Linux, but documenting here in case another OS hits
a SIGILL here.

When CY bit of the mcounteren register is unset, reading the cycle register
will cause illegal instruction exception in the next privilege level ( user
mode or supervisor mode ). See the privileged isa manual section 3.1.11 in
https://github.com/riscv/riscv-isa-manual/releases/latest
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants