Slow FIFO read from LSM6DS3
If I'm not mistaken, your code is a regular Linux application, i.e. it runs in user space. Therefore, each call to read or write requires a context switch from user to kernel space. Most likely the process will also be paused while it waits for the answer from the I2C bus and needs to be rescheduled once the answer is ready. That has its cost.

Given your data, your code reads 3120 bytes from the sensor in about 2 seconds. Each byte requires two operations (a read and a write call):

2s ÷ (*3120* × 2) = 0.32ms


0.32ms sounds about right as the cost for the context switching and process scheduling. The I2C speed is bascially irrelevant. It's the pauses between the I2C transactions that make up the bulk of the cost.

To improve the speed, you will have to reduce the number of context switches, i.e. the number of I2C operations.

An easy solution to cut the number of operations in half is to use i2c_smbus_read_byte_data. It combines writing the regiser address and reading a value into a single operation.

Further optimization depends on the sensor. Usually, there is a way to read many bytes from a FIFO at once. If that's possible, i2c_smbus_read_block_data might be helpful. I'm not sure the LSM6DS3 supports it. Its documentation left me clueless.