VectorEnv/ThreadedVectorEnv have worse performance than Env
See original GitHub issue❓ Questions and Help
Hi,
I wrote the following script to compare the performance of different types of habitat Envs.
I expected the vectorised environments to run faster than the normal Env, however got the following results:
Normal Env took 299.7s to take 500 steps in 14 environments
VectorEnv took 484.4s to take 500 steps in 14 environments
ThreadedVectorEnv took 2345.4s to take 500 steps in 14 environments
Can anyone explain this result please?
BTW: This was run on an RTX 2080Ti GPU.
"""
example.py
==================================================
This is an example of how to use the habitat environment class.
"""
import habitat
from habitat_baselines.utils.env_utils import (
make_env_fn,
construct_envs,
construct_threaded_envs,
)
from habitat_baselines.config.default import get_config
def example():
"""
Initialises a `habitat.Env` environment, then takes random steps.
"""
baseline_config = get_config("configs/tasks/pointnav.yaml")
config = habitat.get_config("configs/tasks/pointnav.yaml")
config.defrost()
config.TASK_CONFIG = baseline_config.TASK_CONFIG
config.freeze()
env_class = habitat.Env
env = make_env_fn(config, env_class)
n_steps = 500
n_episodes = env.number_of_episodes
for episode in range(n_steps):
count_steps = 0
_ = env.reset()
scene_name = env.current_episode.scene_id.split(sep="/")[-1].strip(".glb")
print(f"\nStarting episode {episode+1}/{n_episodes} in {scene_name}...")
print("Stepping around...")
for step in range(n_steps):
action = env.action_space.sample()
while action["action"] == "STOP":
action = env.action_space.sample()
_ = env.step(action)
count_steps += 1
print(
f"Episode {episode+1} in scene {scene_name} finished after {count_steps} steps."
)
def vector_example():
"""
Initialises a `habitat.VectorEnv` environment, then takes random steps.
"""
baseline_config = get_config("configs/tasks/pointnav.yaml")
config = habitat.get_config("configs/tasks/pointnav.yaml")
config.defrost()
config.TASK_CONFIG = baseline_config.TASK_CONFIG
config.NUM_ENVIRONMENTS = 14
config.SENSORS = baseline_config.SENSORS
config.SIMULATOR_GPU_ID = 0
config.freeze()
env_class = habitat.Env
envs = construct_envs(config, env_class)
_ = envs.reset()
n_steps = 500
n_envs = envs.num_envs
n_episodes = envs.number_of_episodes[0]
for episode in range(n_episodes):
count_steps = 0
print(
f"Starting episode {episode}/{n_episodes} in parallel processes across {n_envs} environments."
)
scene_names = [
ep.scene_id.split("/")[-1].strip(".glb") for ep in envs.current_episodes()
]
for i, scene in enumerate(scene_names):
print(f"Stepping around in Environment {i+1}: {scene}..")
for step in range(n_steps):
random_actions = [
action_space.sample() for action_space in envs.action_spaces
]
_ = envs.step(random_actions)
count_steps += 1
print("Episodes finished after {} steps.".format(count_steps))
def threaded_vector_example():
"""
Initialises a `habitat.ThreadedVectorEnv` environment, then takes random steps.
"""
baseline_config = get_config("configs/tasks/pointnav.yaml")
config = habitat.get_config("configs/tasks/pointnav.yaml")
config.defrost()
config.TASK_CONFIG = baseline_config.TASK_CONFIG
config.NUM_ENVIRONMENTS = 14
config.SENSORS = baseline_config.SENSORS
config.SIMULATOR_GPU_ID = 0
config.freeze()
env_class = habitat.Env
envs = construct_threaded_envs(config, env_class)
_ = envs.reset()
n_steps = 500
n_envs = envs.num_envs
n_episodes = envs.number_of_episodes[0]
for episode in range(n_episodes):
count_steps = 0
print(
f"Starting episode {episode}/{n_episodes} in parallel threads across {n_envs} environments."
)
scene_names = [
ep.scene_id.split("/")[-1].strip(".glb") for ep in envs.current_episodes()
]
for i, scene in enumerate(scene_names):
print(f"Stepping around in Environment {i+1}: {scene}..")
for step in range(n_steps):
random_actions = [
action_space.sample() for action_space in envs.action_spaces
]
_ = envs.step(random_actions)
count_steps += 1
print("Episodes finished after {} steps.".format(count_steps))
if __name__ == "__main__":
import time
start = time.time()
example()
end = time.time()
example_time = end - start
start = time.time()
vector_example()
end = time.time()
vector_example_time = end - start
start = time.time()
threaded_vector_example()
end = time.time()
threaded_example_time = end - start
print(
f"\n\n\nNormal Env took {round(example_time, 1)}s to take 500 steps in 14 Environments"
)
print(
f"VectorEnv took {round(vector_example_time, 1)}s to take 500 steps in 14 Environments"
)
print(
f"ThreadedVectorEnv took {round(threaded_example_time, 1)}s to take 500 steps in 14 Environments"
)
Issue Analytics
- State:
- Created 3 years ago
- Comments:6 (1 by maintainers)
Top Results From Across the Web
SubprocVecEnv performance compared to gym.vector ...
Hi, I'm trying to use SubProcVecEnv to create a vectorized environment and use it in my own PPO implementation. I have a couple...
Read more >Should I prefer array over vector for performance? [duplicate]
No. (to satisfy the comment pedants, no, you should not "prefer" arrays over vectors for performance, but sure, you should "consider" using ...
Read more >Java 18: Vector API — Do we get free speed-up? - Medium
The performance speed-up results from applying the same operation on more than one “piece of data” within one CPU cycle. As a simple...
Read more >Top 20 C++ multithreading mistakes and how to avoid them
Mistake # 1: Not using join() to wait for background threads before terminating an application. If we forgot to join a thread or...
Read more >Configuration Handling — Flask Documentation (1.1.x)
The ENV and DEBUG config values are special because they may behave inconsistently if changed after the app has begun setting up. In...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Also, I’ll clarify that
ThreadedVectorEnv
is not actually parallel (it uses python threads). That exists solely for debugging purposes and it being slow is a (necessary, albeit unfortunate) side effect of it fulfilling that role. It is not intended for use when performance matters.Closing the issue because it has not had recent activity.