Test with D47639 for `AFMT_FLOAT`,Apply D47639 to test sound.
---
Below is a benchmark for `AFMT_FLOAT` operations in `pcm_sample_read()` and `pcm_sample_write()`. aka `AFMT_F32_NE`.The results are in cycles, On a little-endian machineand are measured by adding 2 `rdtscp()` calls in `pcm_sample_read()` and `pcm_sample_write()` respectively - one at the start and one at the end, to test `AFMT_F32_BE` explicitly, you can apply the following patch to beep(1) instead:and calculating the difference.
The test program is a simple loopback program that reads and writes zeroes 512 times:
```
diff --git a/usr.bin/beep/beep.c b/usr.bin/beep/beep.c#include <sys/soundcard.h>
#include <err.h>
index 151236b4825b..96e13cc86e9d 100644#include <fcntl.h>
--- a/usr.bin/beep/beep.c
+++ b/usr.bin/beep/beep.c
@@ -152,7 +152,7 @@ usage(void)
#include <unistd.h>
int
main(int argc, char **argv[])
{
- uint32_t *buffer;sample;
+ float *buffer;int fd, fmt, chans, rate, n;
if ((fd = open(argv[1], O_RDWR)) < 0)
err(1, "open(%s)", argv[1]);
size_t slope;chans = 1;
size_t size;if (ioctl(fd, SNDCTL_DSP_CHANNELS, &chans) < 0)
err(1, "ioctl(SNDCTL_DSP_CHANNELS)");
size_t off;fmt = AFMT_S16_LE;
@@ -208,9 +208,9 @@ main(int argc, char **argv)
if (ioctl(fd, SOUND_PCM_WRITE_CHANNELSSNDCTL_DSP_SETFMT, &c) != 0&fmt) < 0)
errx(1, "ioctl SOUND_PCM_WRITE_CHANNELS(1) failed");(SNDCTL_DSP_SETFMT)");
- c = AFMT_S32_NE; rate = 48000;
+ c = AFMT_F32_BE;
if (ioctl(fd, SNDCTL_DSP_SETFMTPEED, &c) != 0&rate) < 0)
- errx(1, "ioctl SNDCTL_DSP_SETFMT(AFMT_S32_NE) failed");
+ errx(1(1, "ioctl (SNDCTL_DSP_SETFMT(AFMT_F32_BE) failed");PEED)");
if (ioctl(f, SNDCTL_DSP_SPEED,for (n = 512; &sample_rate) != 0)n--;) {
errx(1, "ioctl SNDCTL_DSP_SPEED(%d) failed", sample_rate); = 0;
@@ -251,7 +251,15 @@ main(int argc, char **argv)
else if (off > (if (read(fd, &sample, size - slope)of(sample)) < 0)
sample = sample * (size - off - 1) / (float)slope;
- buffer[off] = sample * 0x7fffff00;err(1, "read");
+ int32_t tmp;f (write(fd, &sample, sizeof(sample)) < 0)
+ memcpy(&tmp, &sample err(1, sizeof(tmp));"write");
+ }
tmp = ((uint32_t)tmp & 0x000000ff) << 24 | close(fd);
+ (tmp & 0x0000ff00) << 8 |}
+ (tmp & 0x00ff0000) >> 8```
The sound card used is a Focusrite Scarlett Solo (`snd_uaudio(4)`), with VCHANs disabled to simplify the test.
| function | cycles |
+ (tmp & 0xff000000) >> 24;| `pcm_sample_read(AFMT_S32_LE)` | 330.806 |
+ memcpy(&sample, &tmp, sizeof(sample));| `pcm_sample_write(AFMT_S32_LE)` | 183.298 |
+| `pcm_sample_read(AFMT_F32_LE)` | 3246.6 |
+ buffer[off] = sample;
}| `pcm_sample_write(AFMT_F32_LE)` | 1893.8 |
if (write(f, buffer, size * sizeof(buffer[0])) !=
```The `AFMT_FLOAT` operations seem to be ~10x more expensive.